-
Notifications
You must be signed in to change notification settings - Fork 96
Optimize query parameter key=value parsing #3200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Generate changelog in
|
✅ Successfully generated changelog entry!What happened?Your changelog entries have been stored in the database as part of our migration to ChangelogV3. Need to regenerate?Simply interact with the changelog bot comment again to regenerate these entries. |
651429c
to
53fb026
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR optimizes query parameter parsing in DialogueFeignClient.FeignEndpoint#renderPath
to improve performance in high-throughput RPC scenarios. The optimization replaces Guava's Splitter
with vectorized indexOf
operations to reduce allocation overhead and improve parsing efficiency.
- Replaces
QUERY_VALUE_SPLITTER
with directindexOf
operations for key=value parsing - Adds comprehensive test coverage for query parameter edge cases including empty values and malformed parameters
- Maintains existing error handling behavior while improving performance
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
DialogueFeignClient.java | Replaces Guava Splitter with direct string operations for query parameter parsing |
JaxRsClientDialogueEndpointTest.java | Adds test coverage for query parameter parsing edge cases and error conditions |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
List<String> keyValuePair = QUERY_VALUE_SPLITTER.splitToList(querySegment); | ||
if (keyValuePair.size() != 2) { | ||
int equalsIndex = querySegment.indexOf(QUERY_KEY_VALUE_SEPARATOR); | ||
if (equalsIndex > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition equalsIndex > 0
excludes valid query parameters that start with '=' (empty key). Based on the test cases, it appears '=' should be handled as a valid parameter with empty key and empty value. The condition should be equalsIndex >= 0
to handle this case.
if (equalsIndex > 0) { | |
if (equalsIndex >= 0) { |
Copilot uses AI. Check for mistakes.
@@ -417,14 +418,17 @@ public void renderPath(ListMultimap<String, String> params, UrlBuilder url) { | |||
if (queryParamsStart != -1) { | |||
String querySegments = trailing.substring(queryParamsStart + 1); | |||
for (String querySegment : QUERY_SPLITTER.split(querySegments)) { | |||
List<String> keyValuePair = QUERY_VALUE_SPLITTER.splitToList(querySegment); | |||
if (keyValuePair.size() != 2) { | |||
int equalsIndex = querySegment.indexOf(QUERY_KEY_VALUE_SEPARATOR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to ensure that there aren't more than 2 segments.
if (equalsIndex > 0) { | ||
String key = querySegment.substring(0, equalsIndex); | ||
String value = querySegment.substring(equalsIndex + 1); | ||
url.queryParam(urlDecode(key), urlDecode(value)); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd prefer if we wrote this as if-throw to avoid additional nesting in the non-exceptional case.
Before this PR
In services that make high throughput RPCs with small responses (think similar clients of timestamps, locks, authorization results, etc. as #3114 ),
String#charAt
&com.google.common.base.Splitter#splitToList
pop up as hot methods & allocators due toDialogueFeignClient.FeignEndpoint#renderPath
query parameterkey=value
parsing.After this PR
==COMMIT_MSG==
Use vectorized
indexOf
to improve query parameter parsing and reduce allocation overhead.==COMMIT_MSG==
Possible downsides?