Understanding the impact of Roslyn Analyzers on build time

 
 
  • Gérald Barré

Roslyn analyzers analyze your code for style, quality and maintainability, design and other issues. .NET includes builtin analyzers (Microsoft.CodeAnalysis.NetAnalyzers), and it's very common to include a few other analyzers such as Microsoft.VisualStudio.Threading.Analyzers, Meziantou.Analyzer, or StyleCop.Analyzers.

Roslyn analyzers run while building the projects. If you enable lots of rules, it could add a few seconds to a few minutes to the compilation time. While this ensures code quality, it reduces your productivity. So, maybe some rules should be enabled only on CI or on live analysis. First, you need to find which rules are taking time.

Roslyn can measure the execution of each rule. To do so, you need to add <ReportAnalyzer> to your project:

csproj (MSBuild project file)
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <ReportAnalyzer>true</ReportAnalyzer>
  </PropertyGroup>
</Project>

Now, you can build using the binary log option:

Shell
dotnet build my_project.csproj /binaryLogger

This should create a new file named msbuild.binlog:

You can open this file using the Binary Log Viewer. If you scroll down, you'll find the "Analyzer Summary" section. This section shows the execution for each rule:

In the previous screenshot, you can see that the SonarAnalyzer takes more than 4 minutes. As rules can run in parallel, this doesn't mean that it adds about 4 minutes to the build. This depends on how much Roslyn can parallelize the work and the number of CPUs available. However, this is a huge hit on the compilation time.

Now that you have metrics, you can consider changing the way you run analyzers in your projects. There are 3 MSBuild properties you can use to control analyzer behavior:

  • RunAnalyzersDuringBuild controls whether analyzers run at build time.
  • RunAnalyzersDuringLiveAnalysis controls whether analyzers analyze code live at design time.
  • RunAnalyzers disables analyzers at both build and design time. This property takes precedence over RunAnalyzersDuringBuild and RunAnalyzersDuringLiveAnalysis.
csproj (MSBuild project file)
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
    <RunAnalyzersDuringLiveAnalysis>false</RunAnalyzersDuringLiveAnalysis>
    <RunAnalyzers>false</RunAnalyzers>
  </PropertyGroup>
</Project>

For example, you can set RunAnalyzersDuringBuild to false while developing and set it to true on CI. This way, you can quickly build and debug your project while still getting diagnostics from the live analysis (visible in the Error Window in Visual Studio). However, RunAnalyzersDuringBuild should be set to true on the CI environment.

csproj (MSBuild project file)
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
    <RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
  </PropertyGroup>
</Project>

On CI, you can build using dotnet build /p:RunAnalyzersDuringBuild=true

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub