CSharpGuidelines icon indicating copy to clipboard operation
CSharpGuidelines copied to clipboard

CSharpGuidelinesAnalyzer causes extremely slow builds in .NET 10

Open bkoelman opened this issue 1 month ago • 1 comments

When building in Visual Studio 2026 with CSharpGuidelinesAnalyzer enabled, I'm observing extremely slow builds. Upon inspection, the analysis takes much longer than usual (several minutes to build a single project). ~This doesn't happen when building from the command line with dotnet build.~ I haven't tried in Rider.

Image Image

I don't think the times in the binlog are actually correct. It definitely did not take anywhere near the reported 44 minutes to complete the build. Interestingly, other analyzers are also reported to be quite slow.

It's still unclear to me why this happens, but I thought to reach out in case others are observing something similar. Please share your experiences so we can better understand what's causing this. I'm posting here for greater visibility.

To measure your own codebase, use the following steps:

  • From a command prompt, run:
    set MSBUILDDEBUGENGINE=1
    set MSBUILDDEBUGPATH=c:\binlogs
    md c:\binlogs
    devenv.exe
    
  • Create a Directory.Build.props in the root of your codebase with contents:
    <Project>
      <PropertyGroup>
        <ReportAnalyzer>true</ReportAnalyzer>
      </PropertyGroup>
    </Project>
    
  • Open your solution, build the project(s) you want to measure, and close VS
  • Open the first file created in c:\binlogs in MSBuild Structured Log Viewer
  • Navigate to the Analyzer Summary top-level node and expand

bkoelman avatar Nov 19 '25 02:11 bkoelman

Update: I forgot to pass --no-incremental to dotnet build initially. After doing so, it is similarly slow:

Build succeeded in 9,2s

vs:

Build succeeded in 52,6s

To turn off analyzers quickly, add a Directory.Build.targets to the root of your repository, for example:

<Project>
  <Target Name="DisableSlowAnalyzers" BeforeTargets="CoreCompile">
    <ItemGroup>
      <Analyzer Remove="@(Analyzer)" Condition="'%(Filename)' == 'xunit.analyzers'"/>
      <Analyzer Remove="@(Analyzer)" Condition="'%(Filename)' == 'CSharpGuidelinesAnalyzer'"/>
    </ItemGroup>
  </Target>
</Project>

Note that you can make it conditional. For example, to keep local builds in your IDE fast, while taking the performance hit during release builds in your CI environment:

<Target Name="DisableSlowAnalyzers" Condition="'$(Configuration)' == 'Debug'" BeforeTargets="CoreCompile">

The cause seems to be a regression in the C# compiler, tracked at https://github.com/dotnet/roslyn/issues/80756. Please upvote there if you care about getting it fixed.

bkoelman avatar Nov 20 '25 23:11 bkoelman