vs-threading icon indicating copy to clipboard operation
vs-threading copied to clipboard

Improve Performance of VSTHD110

Open KylePolansky opened this issue 3 years ago • 2 comments
trafficstars

Is your feature request related to a problem? Please describe.

I'm having slow performance of VSTHD110 after #777 (Upgrading from v16.9.60 to v16.10.56).

My primary (private) solution file compiles in ~53s without this analyzer, and ~1m35s when enabling this analyzer (a ~45% increase). Old version v16.9.60 compiles in ~58s. There's a pronounced CPU bottleneck in new versions such that machines with fewer cores see a nearly linear slowdown (as opposed to more cores typically having diminishing returns due to build tree dependency ordering). I believe this performance impact is excessive for a single analyzer rule.

The slowdown appears to be in the GetAwaitableTypes method, specifically around namespaceOrTypeSymbol.GetMembers() being called recursively for each INamespaceOrTypeSymbol.

Describe the solution you'd like

I'd like to investigate this method and see if there's a faster way to determine if a method is awaitable.

Describe alternatives you've considered

I tried caching the results of this method similar to customAwaitableTypes without much luck (maybe ~1s saving, likely within margin of error).

I explored some other ways to get methods by name from a compilation (since we already have typeSymbol), but I'm not familiar enough with code analysis libraries to get anything working in the past few hours.

Additional context

I attempted the following modifications in GetAwaitableTypes for performance testing, NOT correctness, in attempt to isolate the performance bottleneck:

replacing:

case INamespaceOrTypeSymbol nsOrType:
    ...

with:

case INamespaceOrTypeSymbol nsOrType:
    continue;

adds only 5s of build overhead compared to no analyzer, which I believe is acceptable performance.

replacing:

case IMethodSymbol method:
    ...

with:

case IMethodSymbol method:
    continue;

has no significant performance change over the latest analyzer version.

KylePolansky avatar Dec 07 '21 07:12 KylePolansky

In our project time increase is about 200%, from 30s to 90s. I'm not sure which of the rules causes that, but it is too much.

kemsky avatar Jul 27 '22 15:07 kemsky

@kemsky, can you use perfview to collect a trace of your compilation and share it with us?

AArnott avatar Jul 27 '22 16:07 AArnott

I have been investigating the increased build time of our (quite large) solution. It turns out that the increase came after we added a reference to the Microsoft.VisualStudio.Threading library. VSTHD110 was the biggest culprit. Disabling it doubled the build time in our case.

Vertygo avatar Dec 07 '22 12:12 Vertygo

Disabling it doubled the build time in our case.

Thanks for the feedback, @vertygo. I'll assume you meant "cut the build time in half" rather than doubled it. :)

AArnott avatar Dec 07 '22 13:12 AArnott

Disabling it doubled the build time in our case.

Thanks for the feedback, @vertygo. I'll assume you meant "cut the build time in half" rather than doubled it. :)

My bad, that is correct @AArnott

Vertygo avatar Dec 07 '22 17:12 Vertygo

This looks fixed in version 17.5.22. Time spent in VSTHRD110 reduced from 10:20.798 to 40.545 seconds when looking at the binlog in MSBuild Log Viewer under the "Analyzer Summary" section for our solution.

  1. install analyzer version 17.4.33
  2. perform build capturing analyzer report msbuild solution_name.sln /t:rebuild /bl /v:m /m /p:reportanalyzer=true
  3. observe 10:20.798 for VSTHRD110
  4. upgrade analyzer version to 17.5.22
  5. perform build capturing analyzer report msbuild solution_name.sln /t:rebuild /bl /v:m /m /p:reportanalyzer=true
  6. observe 40.545 seconds for VSTHRD110

bwilliams1 avatar Feb 03 '23 20:02 bwilliams1