Skip to content

Performance: reduce per-node analyzer costs and commonize duplicated helper code #455

Description

@credfeto

All 26 analyzers in src/FunFair.CodeAnalysis register per-syntax-node callbacks (several on InvocationExpression or SimpleMemberAccessExpression, which fire for every call / member access in every file of every consuming build), so per-node costs multiply enormously across builds. A survey found a consistent set of avoidable per-node costs and duplicated helper-shaped code. This issue tracks a phased optimization + commonization pass, broken into the sub-issues below — each phase lands as its own PR, verified against the full test suite and benchmarks with no change in the diagnostics produced. Micro-optimizations are explicitly in scope — small per-node savings add up over thousands of builds.

Constraints: netstandard2.0, LangVersion latest, Roslyn (Microsoft.CodeAnalysis.CSharp) 5.3.0. Record structs and collection expressions are fine; net6+ BCL string/Span helpers are not available.

Good exemplar patterns already in the codebase to copy: InternalsVisibleToDiagnosticsAnalyzer, ProhibitedSubstituteForUsageInTestBaseDiagnosticsAnalyzer and SuppressMessageDiagnosticsAnalyzer (compilation-start GetTypeByMetadataName bail-out + cached-symbol SymbolEqualityComparer comparisons).

Work breakdown

Verification requirements (every phase)

  1. Full test suite green after each phase; each phase lands as its own PR.
  2. Benchmark before/after per phase; allocation ceilings in the benchmark asserts must not rise (tighten them where a phase reduces allocations).
  3. No behavioral changes: the set of diagnostics produced for the existing test corpus must be identical — this is a perf-only pass. The correctness call-out (Investigate suspected self-comparison bug in ForceMethodParametersInvocationsDiagnosticsAnalyzer #461) goes in its own PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    AI-WorkWork for an AI Agent

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions