-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
♻️Refactor: Simplify content negotiation code #2865
Conversation
The implementation of forEachParameter was upstreamed to fasthttp, so use that version instead of maintaining our own.
The previous implementation of content negotiation used some difficult to understand techniques in order to reduce allocations, potentially hurting maintainability. The more natural approach for storing and comparing unordered media-type parameters is to utilize maps. While the resulting code still isn't as simple as it could be, it's a step closer. To reduce allocations, we use a sync.Pool. This actually reduces in fewer allocations than before at 3 or more parameters. The net result is nearly identical performance for zero parameters, almost-as-good performance for 1-2 parameters, and better performance for 3+ parameters.
I haven't had the chance to do a full review as I’m 🤧 and examining the PR on mobile. I'll conduct a more in-depth analysis before approving the PR. Overall the changes appear positive. The one thing I’m seeing is, considering that real-world scenarios often involve fewer than three parameters, the benchmarks suggest a more noticeable performance reduction. The performance trade-off seems to range from approximately 8% to 54% for these scenarios. |
Thanks for reviewing. That said, the biggest reason I did this refactor was for code clarity, so it's probably only worth the slice => map refactor if it leads to easier to understand code. The switch to fasthttp.VisitHeaderParams can be done separately. I can also repeat the same k6 benchmarks on some weaker armv7 embedded linux devices I have access to in order to see more exaggerated circumstances if we'd like to see more varied statistics. |
Description
The implementation of forEachParameter was upstreamed to fasthttp, so use that version instead of maintaining our own.
The previous implementation of content negotiation used some difficult to understand techniques in order to reduce allocations, potentially hurting maintainability. The more natural approach for storing and comparing unordered media-type parameters is to utilize maps. While the resulting code still isn't as simple as it could be, it's a step closer.
To reduce allocations, we use a sync.Pool. This actually reduces in fewer allocations than before at 3 or more parameters. The net result is nearly identical performance for zero parameters, almost-as-good performance for 1-2 parameters, and better performance for 3+ parameters.
Also tested performance using k6, see below for details.
Changes Introduced
List the new features or adjustments introduced in this pull request. Provide details on benchmarks, documentation updates, changelog entries, and if applicable, the migration guide.
There is no API change in this PR.
Type of Change
Please delete options that are not relevant.
Checklist
Before you submit your pull request, please make sure you meet these requirements:
Benchmarks
k6 benchmarks
Server
Script
PR
Main Branch