-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Refactor Encoding to split fast-path and fallback logic #23098
Refactor Encoding to split fast-path and fallback logic #23098
Conversation
The unit test failures in CoreFX are expected with this change because this change also resolves https://github.com/dotnet/coreclr/issues/23020. Some of the unit tests assert the buggy behavior and need to be fixed up in corefx directly. |
@jkotas - here are some initial perf numbers from the refactored run. (Note: no vectorization has yet been introduced.) (Perf numbers outdated - see #23098 (comment) instead.) As expected, for very short strings the overhead of invoking the fallback logic is high. The fewer invalid characters there are the greater we're able to make progress within the fast-path methods, so the actual performance depends on the ratio of valid-to-invalid chars. This was just testing |
Looks reasonable to me. Thanks |
https://github.com/dotnet/coreclr/blob/master/tests/CoreFX/CoreFX.issues.json to disable the tests to make the PR green. |
And here are the (Perf results outdated - see #23098 (comment).) |
PR is now out of draft stage. Thanks @jkotas for getting it this far! |
src/System.Private.CoreLib/shared/System/Text/DecoderFallback.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/System/Text/ASCIIEncodingSealed.cs
Outdated
Show resolved
Hide resolved
cc @stephentoub |
The latest iteration has this moved around a bit (for Here, Since I also tweaked |
Perf results from latest iteration, using both normal
baseline = The state of the world today. |
Yes, this looks better!
+1 |
I merged because the PR was approved, but if anybody has any additional comments leave them here or email me and I'll open another PR to address them. Thanks all for the feedback! |
…lr#23098) This refactoring is limited to ASCIIEncoding at the moment, but it can easily be applied to UTF-8 / UTF-16 / UTF-32. High-level changes: - Fallback logic has been split from the fast-path, improving performance of GetBytes and similar routines. - All of the plumbing of when to invoke the fallback logic and how to manage leftover data has been moved into the base class. - Almost all of the logic except for the fast-path is now written in terms of verifiable code (Span and ReadOnlySpan). - Minor bug fixes in EncoderNLS.Convert (see https://github.com/dotnet/coreclr/issues/23020). Commit migrated from dotnet/coreclr@43a5159
This is related to #22516, where it was suggested I work in another branch to mechanically separate all of the fallback infrastructure out of the derived
Encoding
classes and into a common base class. This PR represents what the change would look like forASCIIEncoding
, though UTF8 / UTF16 / UTF32 would look similar.In particular, note that all fallback buffer related logic has been removed from
ASCIIEncoding
and pushed down to the base type. Additionally, theASCIIEncoding
class doesn't concern itself withEncoderNLS
/DecoderNLS
(aside from instantiating them). All of this coordination has been pushed down so that it can be shared across allEncoding
-derived types.This is marked WIP because I'm still making minor iterations to it to answer some lingering questions. Is it worthwhile to add methods directly to
ASCIIEncodingSealed
, for instance? Doing so allows us to make assumptions about what optimizations are valid for theEncoding
instance.I've not yet had an opportunity to perform benchmarking against this. I hope to get to this Thursday afternoon or Friday. My expectation is that it will perform better than baseline for calls directly to
ASCIIEncoding.GetBytes
and related APIs since they immediately dispatch to fast-path logic. Calls toEncoderNLS.Convert
may have more invocation overhead compared to baseline due to span shuffling and an extra virtual dispatch. I don't think this extra overhead will affect many applications in practice because I don't believeEncoderNLS.Convert
exists frequently in hot paths, but even so the pending vectorization of these code paths (see #22516) should make up for it./cc @jkotas, who has given significant feedback over the past week as this was being developed; and @tarekgh and @layomia as FYI