Skip to content

Conversation

@ToddGrun
Copy link
Contributor

@ToddGrun ToddGrun commented May 5, 2025

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.

  1. 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.

  2. 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.

  3. 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 ***
image

*** With IsOptionName change ***
image

*** Without TryParseOption change ***
image

*** With TryParseOption change ***
image

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.
@ghost ghost added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels May 5, 2025
@ToddGrun ToddGrun changed the title *** WIP: Targeted perf changes to CommandLineParser Targeted perf changes to CommandLineParser May 6, 2025
@ToddGrun ToddGrun marked this pull request as ready for review May 6, 2025 14:44
@ToddGrun ToddGrun requested a review from a team as a code owner May 6, 2025 14:44
@ToddGrun
Copy link
Contributor Author

ToddGrun commented May 6, 2025

@dotnet/roslyn-compiler -- This is ready for review.

@ToddGrun
Copy link
Contributor Author

ToddGrun commented May 7, 2025

@dotnet/roslyn-compiler -- PTAL, thanks!

@ToddGrun
Copy link
Contributor Author

ToddGrun commented May 8, 2025

@dotnet/roslyn-compiler -- need one more review, thanks!

}

if (!inQuotes && separators.IndexOf(c) >= 0)
else if (!inQuotes && separators.IndexOf(c) >= 0)
Copy link
Member

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.

Copy link
Contributor Author

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.

ToddGrun added 2 commits May 8, 2025 06:27
2) Use Contains(c) instead of IndexOf(c) >= 0
@ToddGrun ToddGrun merged commit c87e204 into dotnet:main May 8, 2025
24 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone May 8, 2025
333fred added a commit to 333fred/roslyn that referenced this pull request May 8, 2025
* 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
  ...
@RikkiGibson RikkiGibson modified the milestones: Next, 18.0 P1 Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants