-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Use IndexOfAny(char, char) with Span #39743
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
Use IndexOfAny(char, char) with Span #39743
Conversation
Use AsSpan().IndexOfAny(char, char) rather than pre-allocate an array for string.IndexOfAny(params char[]).
javiercn
left a comment
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 good to me!
|
I just realised that based on the benchmark result for |
|
Thanks for contributing this, @martincostello! I can sort of speculate about why the However I don't have any intuition for why |
A fair question. Looking at the source, my guess would be that maybe it's due to the aggressive inlining? Otherwise the implementations seem to ultimately go to the same place to me. |
Agreed, that looks like the only difference (assuming that So if I'm reading this correctly, the optimization in this PR does have a behavioral difference, in that the old version would throw for a null input, and the new one won't. However I don't think there can be a null input so that's OK. |
This is old routing, so it doesn't really impact anything :) |
|
Thanks @martincostello! |
Did you try this on .NET 7? I would expect the gap to be smaller (in particular between IndexOfAny_String and IndexOfAny_Span_Array), and indeed this is what I see when I run your benchmark locally on my machine with .NET 6:
and .NET 7:
If you have a small set (e.g. one, two, or three) of const chars, there are benefits to just using the span-based overloads that take those chars directly, as there's no need for the additional static field, additional array, or extracting the chars from the array . But in cases where you already have an array or string of the chars to search for, there shouldn't be a meaningful difference between calling string.IndexOfAny and string.AsSpan().IndexOfAny. |
|
Hi @stephentoub. 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. |
No I didn't try it out with .NET 7 - mainly because I just threw them into an existing console app I had set up and didn't think to point it at one of the alpha builds. Thanks for taking a look and explaining the difference in the array case. |
|
Hi @martincostello. 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. |
Use ROS.IndexOfAny(char, char)
Use
IndexOfAny(char, char)withReadOnlySpan<char>.Description
Use
AsSpan().IndexOfAny(char, char)rather than pre-allocate a static array for use withIndexOfAny(params char[])on a string.I spotted the array in
DefaultFileVersionProviderwhile working on #39738 so thought I'd see if there were any that could be removed in lieu of overloads that just took the characters without an array. This PR updates all the ones I found that were in projects with TFMs that supported it, except for the usages inRoutePatternFactorythat use an array of 5 characters in multiple places.I wrote a quick microbenchmark comparing the two approaches with .NET 6, and using the span version does appear to give a performance improvement.
Benchmarks
Results
Code
Details