-
Notifications
You must be signed in to change notification settings - Fork 4.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
Solve recently introduce ASCII regression #80709
Conversation
* one less method call * one less pinning * don't create a Span out of pointer just to fix it and get the pointer
Tagging subscribers to this area: @dotnet/area-system-text-encoding Issue DetailsOne of the goals I had in #75012 was to replace the usage of internal helpers with new public API calls. Initially we wanted to make Here I am removing the redundant call to fixes #80247
|
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.
LGTM. I assume we have a good test coverage for the changed APIs.
I've applied no merge label as I am about to apply the same pattern in few other places and it would be better to merge of all of them in a single PR. |
… overhead matters for small inputs
If this overhead resulted in a measurable regression, does that suggest there's something to be changed about the public APIs? Presumably everyone else using them would hit similar issues? |
The overhead is quite specific to our needs and is visible only for small inputs. Most of the Encoding methods pin the buffer and then just work with raw pointers: runtime/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs Lines 96 to 99 in e9b9489
runtime/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs Lines 114 to 117 in e9b9489
runtime/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs Lines 144 to 147 in e9b9489
We introduced Span-accepting methods that are also pinning the memory and then just passing a pointer to the helper. So, the overhead comes from creating a span (from the pointer and length), pinning the memory (again), having one more method call (to our public method) and doing some basic checks again (like checking for empty span). It’s very little, but here it matters.
runtime/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs Lines 25 to 27 in e9b9489
I've checked if we could get rid of pinning, but plenty of our ASCII helpers assume that the pointer is fixed and implement optimizations that are searching for the first aligned address:
We could switch to using manager pointers and remove the optimizations that try to take advantage of the alignment, but it would be very hard to achieve performance parity. FWIW I am not happy about making these changes, as it’s as step back s but it seems to be the lesser evil in this particular case. |
One of the goals I had in #75012 was to replace the usage of internal helpers with new public API calls.
Initially we wanted to make
Ascii.GetIndexOfFirstNonAsciiChar
public, but at the end we decided to keep it internal.Here I am removing the redundant call to
Ascii.GetIndexOfFirstNonAsciiChar(ROS)
with a call to the helper method that accepts a pointer and the length. What we get is one less method call, one less span creation and pinning.fixes #80247