Understanding the impact of Roslyn Analyzers on build time
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:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<ReportAnalyzer>true</ReportAnalyzer>
</PropertyGroup>
</Project>
Now, you can build using the binary log option:
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 overRunAnalyzersDuringBuild
andRunAnalyzersDuringLiveAnalysis
.
<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.
<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
- MSBuild Command line reference - Switches for loggers
- Binary Log Viewer
- Disable source code analysis for .NET
Do you have a question or a suggestion about this post? Contact me!