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
HttpSys request headers Keys and Count both allocate #45156
Conversation
Thanks for your PR, @ladeak. Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
Could you include the microbenchmark in the PR? We like to keep those for future use 😃 |
Please address the compilation error.
|
You're welcome to try. |
See #44860 (comment) |
I submitted the benchmarks. In my original benchmarks I actually reused a captured |
src/Servers/HttpSys/src/RequestProcessing/RequestHeaders.Generated.tt
Outdated
Show resolved
Hide resolved
@Tratcher and @BrennanConroy please review changes. |
FYI: #45250 |
Have you rebased on #44860 yet? It has new infrastructure that might be helpful here. |
1df2501
to
819b814
Compare
EDIT 2022. 11. 29. : this is obsolete @Tratcher I have rebased to include your latest changes. I addressed all comments. I fixed some space/tabs styling in the .tt file.
** I had to adjust Windows Power Mode (from Recommended to Perf) and replaced a for loop to a while, to get comparable execution time. I think the remaining perf difference is due to where we run the for loop for the known headers (inside RequestHeaders or NativeRequestContext). |
{ | ||
count++; | ||
} | ||
pUnknownHeader++; |
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.
I wonder if using ref byte-s and Unsafe.As / Unsafe.Add could be beneficial here?
Something broke in your latest changes, but since you force-pushed I can't tell what it was. |
I am looking into it. |
The current performance results:
|
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.
Looks like everything is working, nice job.
A few comments on formatting and this should be ready to go.
src/Shared/HttpSys/RequestProcessing/RequestHeaders.Generated.tt
Outdated
Show resolved
Hide resolved
src/Shared/HttpSys/RequestProcessing/RequestHeaders.Generated.tt
Outdated
Show resolved
Hide resolved
src/Shared/HttpSys/RequestProcessing/RequestHeaders.Generated.tt
Outdated
Show resolved
Hide resolved
…cation free, while Keys allocate the string for the header keys that are not known and a list for the result. RequestHeader.Generated.cs has a new HeaderKeys returned as ReadOnlySpan<byte> for accessing the know keys - by avoiding allocation with enumerator or a static list. RequestHeader.Generated.tt is updated, but I don't see it being used to generate the RequestHeader.Generated.cs file. NativeRequestContext provides new implementation to access the header keys and count.
@Tratcher I am sorry, but I ended up force pushing against my original intentions :( |
Thanks for working through this |
This may have caused a regression in the following test: Investigating. |
Let me know how I can help. |
Hi @ladeak. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Nevermind, the new error is related to hostfxr even trying to load the app, that shouldn't be related to any changes here. This was just the first occurance. |
Thank you for looking into. |
Hi @ladeak. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
HttpSys request headers Keys and Count both allocate
Currently Count and Keys allocate strings and arrays and enumerables. This change intends to reduce the cost of allocation.
Description
RequestHeaders's Key and Count has a new implementation. Count is allocation free, while Keys allocate the string for the unknown header keys and a list for the results.
RequestHeader.Generated.cs has a new HeaderKeys returned as ReadOnlySpan for accessing the known keys - by avoiding allocation with enumerator or a static list.
RequestHeader.Generated.tt is updated, however it does not seem be set up to generate the RequestHeader.Generated.cs file.
NativeRequestContext provides new implementation to access the header keys and count.
Added tests to cover changes, it mocks a memory segment that is normally pinned and passed by IIS.
Considered caching the Keys (as the unknown header names are re-allocated every call). However, it could make sense to re-use the cached values in the Extra property getter too, but that would engage further refactoring.
EDIT (2022.11.19):
Note, that the RequestHeader.ResetFlags() method is used for the benchmakrs only. It does not clear cached values, just clears the flags indicating that a value is set.
Performance Measurements
EDIT (Updated 2022.11.19):
Before:
After (see final results in the comments).
Questions
Open question: should we consider re-implementing ContainsKey to gain performance benefits?
EDIT (2022.11.19): will keep it out of scope this PR.
Fixes #44627