Uh oh!
There was an error while loading. Please reload this page.
Add fast path to MemoryExtensions.Trim for input that needs no trimming - #84210
Conversation
…invalid data parsing
stephentoub
commented
Apr 1, 2023
It's often the case that trim is used when no trimming is actually needed. Is there a way to fix this in trim instead by prioritizing that use case? |
EgorBo
commented
Apr 1, 2023
Good point, e.g. rewrite [MethodImpl(MethodImplOptions.AggressiveInlining)]publicstaticReadOnlySpan<char>Trim(thisReadOnlySpan<char>span){// Assume that in the most cases input doesn't need trimmingif(span.Length==0||(span.Length>0&&!char.IsWhiteSpace(span[0])&&!char.IsWhiteSpace(span[span.Length-1]))){returnspan;}returnTrimFallback(span);[MethodImpl(MethodImplOptions.NoInlining)]staticReadOnlySpan<char>TrimFallback(ReadOnlySpan<char>span){intstart=0;for(;start<span.Length;start++){if(!char.IsWhiteSpace(span[start])){break;}}intend=span.Length-1;for(;end>start;end--){if(!char.IsWhiteSpace(span[end])){break;}}returnspan.Slice(start,end-start+1);}} |
EgorBo
commented
Apr 1, 2023
@stephentoub done, it seems to even improve benchmark results. Do I need to do the same for TrimStart/TrimEnd or those are fine and rarely used? |
Uh oh!
There was an error while loading. Please reload this page.
…ns.Trim.cs Co-authored-by: Stephen Toub <stoub@microsoft.com>
Uh oh!
There was an error while loading. Please reload this page.
stephentoub
commented
Apr 1, 2023
I think we can leave those alone for now. They're used much less, and the one hot path I know about in our own code is already guarded. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| break; | ||
| } | ||
| } | ||
| return span.Slice(start, end - start + 1); |
There was a problem hiding this comment.
Why not use the clamp helpers in the fallback?
There was a problem hiding this comment.
Since we add an additional overhead for cases when input does contain whitespaces I decided to have a slightly faster fallback (inlined clamp helpers) - didn't want to mark the helpers always-inlineable. Can revert to clamp helpers if you think an extra 1ns is not worth it
Co-authored-by: Stephen Toub <stoub@microsoft.com>
Profiler states that majority of time during
Guid.Parseis spent inside.Trim()and it seems that if we can trade around 1% of perf for inputs with trailing/leading whitespaces we can get up to 45% boost for other cases, e.g.:Another mystery is why B format is faster than N (reproduces accross multiple runs)
PS: grep.app for Guid.Parse with constant input: https://grep.app/search?q=Guid.Parse%28%22&filter[lang][0]=C%23 (unlikely on hot path but anyway)