Skip to content

Performance degradation in CA1416 on large solution #7105

Open

Description

Analyzer

Diagnostic ID: CA1416

I see performance problem with CA1416 on my solution.

Configuration

  • Solution with ~260 projects and >1m lines of code (not open source, cannot be shared)
  • Problem originally confirmed with dotnet 6 but also confirmed with net 8.
  • Enabled CA1416, solution contains >12k warnings from CA1416
  • Use MSBuild from Visual Studio 17.9 Preview 2: C:\Program Files\Microsoft Visual Studio\2022\Preview\MSBuild\Current\Bin\MSBuild.exe

Reports

Binlog with /p:ReportAnalyzer=true:

Duration = 4:48.075

Analyzer Summary
  1:22.355   Microsoft.CodeAnalysis.NetAnalyzers, Version=8.0.9.2502, Culture=neutral, PublicKeyToken=31bf3856ad364e35
    Microsoft.NetCore.Analyzers.InteropServices.PlatformCompatibilityAnalyzer (CA1416, CA1422) = 40.799 s
    Microsoft.NetCore.Analyzers.Runtime.AttributeStringLiteralsShouldParseCorrectlyAnalyzer (CA2243) = 5.414 s
    Microsoft.NetCore.Analyzers.InteropServices.DisableRuntimeMarshallingAnalyzer (CA1420, CA1421) = 4.463 s
    Microsoft.CodeQuality.Analyzers.QualityGuidelines.DoNotRaiseExceptionsInExceptionClausesAnalyzer (CA2219) = 3.266 s
    Microsoft.NetCore.Analyzers.InteropServices.UseValidPlatformString (CA1418) = 3.028 s
    Microsoft.NetCore.Analyzers.Performance.UseCountProperlyAnalyzer (CA1827, CA1828, CA1829, CA1836) = 2.616 s
    Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.DoNotHideBaseClassMethodsAnalyzer (CA1061) = 1.544 s
    ...

I don't know how to trace MSBuild. MSBuild run from dottrace generate trace without any usefull info. So I attached to Visual Studio ServiceHub.RoslynCodeAnalysisService.exe and Run Code Analysis on Solution:
image

Most of time spend on adding element to ConcurrentDictionary:

private static bool TryGetOrCreatePlatformAttributes(ISymbol symbol, bool checkParents,
    bool crossPlatform, ConcurrentDictionary<ISymbol, PlatformAttributes> platformSpecificMembers,
    SmallDictionary<string, (string relatedPlatform, bool isSubset)> relatedPlatforms, out PlatformAttributes attributes)
{
    if (!platformSpecificMembers.TryGetValue(symbol, out attributes))
    {
        // < some code >

        attributes ??= new PlatformAttributes() { IsAssemblyAttribute = symbol is IAssemblySymbol };
        MergePlatformAttributes(symbol.GetAttributes(), ref attributes, crossPlatform, relatedPlatforms);

        // This one:
        attributes = platformSpecificMembers.GetOrAdd(symbol, attributes);
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions