-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Targeted perf changes to CommandLineParser #78446
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
Targeted perf changes to CommandLineParser #78446
Conversation
Will add more details when speedometer numbers come back from test insertion. Not expected to make a large difference, but this codepath is heavily executed during solution load, which is an area whose perf I'm attempting to improve.
|
@dotnet/roslyn-compiler -- This is ready for review. |
|
@dotnet/roslyn-compiler -- PTAL, thanks! |
|
@dotnet/roslyn-compiler -- need one more review, thanks! |
| } | ||
|
|
||
| if (!inQuotes && separators.IndexOf(c) >= 0) | ||
| else if (!inQuotes && separators.IndexOf(c) >= 0) |
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.
Wouldn't Contains be even faster than IndexOf >= 0? Perhaps also SearchValues would make sense here.
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.
Switched to Contains in commit 2.
Thanks for the tip about SearchValues, I didn't know about that. I think I'm going to pass on that for now, but I'll keep that in the back pocket for the next time I see something like this.
2) Use Contains(c) instead of IndexOf(c) >= 0
* upstream/main: (415 commits) Use lazy initialization for members in CodeFixService (dotnet#78484) Targeted perf changes to CommandLineParser (dotnet#78446) Exclude VS.ExternalAPIs.Roslyn.Package from source-build Add syntax highlighting of ignored directives (dotnet#78458) Fix unexpected conditional state in nullable analysis of conditional access (dotnet#78439) Update RoslynAnalyzers to use Roslyns version Fix source-build by renaming Assets folder to assets Unlist M.CA.AnalyzerUtilities as an expected DevDivInsertion dependency Use a project reference for M.CA.AnalyzerUtilities Rectify status of dictionary expressions (dotnet#78497) Remove unused field Remove unused field Remove using Fix check Update eng/config/PublishData.json Make internal Remove now unused methods from IWorkspaceProjectContext (dotnet#78479) Reduce allocations during SourceGeneration (dotnet#78403) Update Roslyn.sln Merge EditorFeatures.Wpf entirely into EditorFeatures ...
CommandLineParser shows up as surprisingly expensive in the speedometer traces I've been looking at for solution load. This PR attempts a couple small, targeted fixes for a slight improvement.
IsOptionName was doing either 1 or 2 passes in the standard ascii case. Instead, do a length check upfront so that we commonly do 0 passes, and if the lengths match, do 1 pass in the ascii case. In the non-ascii case, fall back to using the ReadOnlySpan's Equals as the code did before. This is a small CPU win reflected by the first two images below.
TryParseOption's calls to IndexOf are showing up in the trace. We can limit the span we search significantly as colon typically is found towards the beginning of arg and arg can be quite long. Small CPU win again, reflected by the 3rd and 4th images below.
ParseSeparatedStrings is a very commonly tread codepath. Small micro-optimizations in the loop to not do the IndexOf call when c is a quote and to check the common condition first.
Test insertion PR: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/634213
*** Without IsOptionName change ***

*** With IsOptionName change ***

*** Without TryParseOption change ***

*** With TryParseOption change ***
