C# Build is slow with SonarQube enabled

Versions:

  • SonarQube: 9.3 (Enterprise Edition)
  • SonarScanner for MSBuild 5.6
  • csharp version 8.34.0.42011
  • Running build from Azure DevOps

When we are building our solution without SonarQube, the build takes about 5 minutes to finish. When we enable SonarQube, it will take about 40 minutes.

I followed the SonarSource guide for investigating the performance of .NET analysis, but I’m not sure how to fasten our build.

I did identify two projects that take most of the time, but I don’t understand why and how to speed this up. Without those two projects, the build time is about 10 minutes. Which is kind of acceptable, but I would prefer to keep analyzing all of those projects.

Some of the longest analysis below. In all cases its the DeadStores rule that takes most time, but even without that particular rule it will take too long.

Total analyzer execution time: 1164.215 seconds.
NOTE: Elapsed time may be less than analyzer execution time because analyzers can run concurrently.

Time (s)    %   Analyzer
 1147.226   98   SonarAnalyzer.CSharp, Version=8.34.0.0, Culture=neutral, PublicKeyToken=c5b62af9de6d7244
  876.555   75      SonarAnalyzer.Rules.CSharp.DeadStores
   64.031    5      SonarAnalyzer.Rules.CSharp.SymbolReferenceAnalyzer
   59.207    5      SonarAnalyzer.Rules.CSharp.PrivateFieldUsedAsLocalVariable
   45.889    3      SonarAnalyzer.Rules.CSharp.TokenTypeAnalyzer
   43.035    3      SonarAnalyzer.Rules.CSharp.InsecureEncryptionAlgorithm
   12.217    1      SonarAnalyzer.Rules.SymbolicExecution.SymbolicExecutionRunner

Total analyzer execution time: 206.981 seconds.
NOTE: Elapsed time may be less than analyzer execution time because analyzers can run concurrently.

Time (s)    %   Analyzer
 177.290   85   SonarAnalyzer.CSharp, Version=8.34.0.0, Culture=neutral, PublicKeyToken=c5b62af9de6d7244
  34.051   16      SonarAnalyzer.Rules.SymbolicExecution.SymbolicExecutionRunner
  28.458   13      SonarAnalyzer.Rules.CSharp.DeadStores
  11.870    5      SonarAnalyzer.Rules.CSharp.DoNotCallGCCollectMethod
  10.041    4      SonarAnalyzer.Rules.CSharp.TokenTypeAnalyzer
   7.907    3      SonarAnalyzer.Rules.CSharp.SymbolReferenceAnalyzer
   7.161    3      SonarAnalyzer.Rules.CSharp.PrivateFieldUsedAsLocalVariable
   5.079    2      SonarAnalyzer.Rules.CSharp.MethodParameterUnused
Total analyzer execution time: 1062.431 seconds.
NOTE: Elapsed time may be less than analyzer execution time because analyzers can run concurrently.

Time (s)    %   Analyzer
1051.641   98   SonarAnalyzer.CSharp, Version=8.34.0.0, Culture=neutral, PublicKeyToken=c5b62af9de6d7244
 511.969   48      SonarAnalyzer.Rules.CSharp.DeadStores
  68.849    6      SonarAnalyzer.Rules.CSharp.TokenTypeAnalyzer
  53.722    5      SonarAnalyzer.Rules.CSharp.DisposableNotDisposed
  30.950    2      SonarAnalyzer.Rules.CSharp.MetricsAnalyzer
  22.448    2      SonarAnalyzer.Rules.CSharp.ExecutingSqlQueries
  21.444    2      SonarAnalyzer.Rules.CSharp.ConfiguringLoggers
  21.035    1      SonarAnalyzer.Rules.CSharp.DoNotHardcodeCredentials
  15.178    1      SonarAnalyzer.Rules.CSharp.CommandPath
  14.651    1      SonarAnalyzer.Rules.CSharp.EncryptionAlgorithmsShouldBeSecure
  14.222    1      SonarAnalyzer.Rules.CSharp.LiteralSuffixUpperCase
  12.801    1      SonarAnalyzer.Rules.CSharp.WeakSslTlsProtocols
  12.620    1      SonarAnalyzer.Rules.CSharp.CreatingHashAlgorithms
  10.308   <1      SonarAnalyzer.Rules.CSharp.BypassingAccessibility
Total analyzer execution time: 70.804 seconds.
NOTE: Elapsed time may be less than analyzer execution time because analyzers can run concurrently.

Time (s)    %   Analyzer
 67.793   95   SonarAnalyzer.CSharp, Version=8.34.0.0, Culture=neutral, PublicKeyToken=c5b62af9de6d7244
 29.007   40      SonarAnalyzer.Rules.CSharp.DeadStores
  7.437   10      SonarAnalyzer.Rules.CSharp.TokenTypeAnalyzer

Hello @Mibe and thanks for contacting us and for using our products!

Maybe we should focus on these two? Can you share the verbose logs of the analysis of these projects (BEGIN, build and END steps)?

1 Like

I will create the log for just one of those projects. The build logfile for the complete solution is > 500MB. I don’t think I’m able to send a private message yet due to my trust level.

We did made improvements already for our builds. We doubled our CPU’s for the build machines, I guess those were the biggest bottleneck for now. The time reduced from 40 minutes to 15 minutes. Didn’t know that SonarQube (or the C# analyzers) had such a big impact on CPU usage.

Yes, indeed they have! I’ve added this point (increase CPU count) to the The SonarSource guide for investigating the performance of .NET analysis, it seems it wasn’t there.

For info, this is what you can expect by further increasing the number of CPUs:

From our experiments, increasing the memory doesn’t help that much, but there can be marginal benefits from increasing RAM as well.

@Mibe could you please share the version of MSBuild / dotnet that you are using?

DeadStores spending 75% of analysis time is an anomaly and I’d like to better understand what’s happening there.

@Andrei_Epure This is the version used: Microsoft (R) Build Engine version 16.7.2+b60ddb6f4 for .NET

Thanks @Mibe. This rule is built on the Roslyn Control Flow Graph and I want to understand if it has a performance problem that we need to fix.

If you disable the SonarAnalyzer.Rules.CSharp.DeadStores rule (S1854) in the Quality Profile and do an analysis of the same project, does the build time improve significantly? Could you please share the Total analyzer execution time: of this project when S1854 is disabled?

Also, could you update your version of SonarQube, to get the latest version of our analyzers? SonarQube 9.3 is not supported anymore (only the latest version and the LTS are supported - see here).

Thank you for helping us improve our products!

Currently I don’t see any significant difference with or without that rule.
The highest spending % for DeadStores is 7%.

That is after the CPU upgrade and with SonarQube 9.5.

1 Like

Thanks. I’ve marked your initial answer as a solution. If you don’t agree, please tell me and I can revert.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.