-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Pattern matching ReadOnlySpan<char> is worse than String #66529
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsDescriptionTrying to use dotnet/csharplang#1881 is resulting in worse performance than calling I've created a repro: https://github.com/eerhardt/SwitchSpanPerf. Just pull this code and The only difference between the two GetNamedColorXXX methods is: Span<char> loweredValue = value.Length <= 128 ? stackalloc char[value.Length] : new char[value.Length];
int charsWritten = value.ToLowerInvariant(loweredValue);
- return loweredValue switch
+ return loweredValue.ToString() switch
{ Regression?No Windows .NET 6
Windows .NET 7
MacOS .NET 6Surprisingly on my MacOS x64 machine on .NET 6 doesn't seem to have this problem.
AnalysisThe only real differences in IL that I see are (left String, right Span):
Comparing the assembly code, this part looks a lot difference:
|
This could greatly be improved by #65288 but it easily hits the "<20 basic blocks" heuristics - I'll see what will happen if I remove that. |
So I've looked at the codegen and it seems to be the main issue here that the IL is just too big - JIT gives up on inlining and register allocation (tracking locals) so we end up with very inefficient codegen for I feel like enabling #65288 unconditionally for at least spans is a good idea |
@EgorBo - do you know why I was seeing this difference on my windows machine but not my mac? |
I suspect it's ABI difference. |
A huge switch like that feels like there should be a better way to match it. A Trie or something like that. |
Feel free to implement dotnet/roslyn#56374 on the Roslyn side ;-) |
Hasn't been approved, plus I'm not sure I need to be in yet another codebase... |
Closed via #66534 |
Description
Trying to use dotnet/csharplang#1881 is resulting in worse performance than calling
Span.ToString()
and matching on that.I've created a repro: https://github.com/eerhardt/SwitchSpanPerf. Just pull this code and
dotnet run -c Release
to run the benchmarks. I've tried both .NET 6 and the latest .NET 7 main branch.The only difference between the two GetNamedColorXXX methods is:
Regression?
No
Windows .NET 6
Windows .NET 7
MacOS .NET 6
Surprisingly on my MacOS x64 machine on .NET 6 doesn't seem to have this problem.
Analysis
The only real differences in IL that I see are (left String, right Span):
At the top where we call ToString and the ComputeHash methods:
Once we've found the correct hash and calling the string
==
method vs.AsSpan
andSequenceEqual
methods:Comparing the assembly code, this part looks a lot difference:
cc @EgorBo @stephentoub
The text was updated successfully, but these errors were encountered: