perf(sourcegen): Single-pass attribute classification by thomhurst · Pull Request #6111 · thomhurst/TUnit (original) (raw)
…cation
Closes #6106
- InterfaceCache: add a real per-type cache of implemented interface names backed by a ConditionalWeakTable<ITypeSymbol, ImmutableHashSet>. Keying on the symbol ties each entry's lifetime to the symbol/Compilation, so the cache is reclaimed on collection and cannot leak symbols across compilations in long IDE sessions (the failure mode a static dictionary would cause). ImplementsInterface now does an O(1) set lookup instead of walking AllInterfaces on every call.
- TestMetadataGenerator.CollectConcreteInstantiations: replace the 6-8
repeated
.Where(...).ToArray()scans over MethodAttributes with a single classification foreach partitioning into null-init buckets. Buckets are independent so multi-membership (e.g. MethodDataSourceAttribute is also an IDataSourceAttribute) is preserved exactly. - MethodExtensions.GetTestAttribute: FirstOrDefault(lambda) -> foreach + early return, hoisting the well-known name out of the loop.
- CodeWriter.GetIndentation: drop Enumerable.Repeat on the cache-miss path; fast path for single-space indent, StringBuilder loop otherwise. Output is byte-identical.
Generated source output is unchanged - verified by the snapshot tests in TUnit.Core.SourceGenerator.Tests (116 passed, 1 pre-existing skip, 0 failed, no .received.txt produced). No ISymbol is stored in incremental pipeline nodes; only post-Collect consumers touch symbols.
[](/apps/claude)
…-> InterfaceHelper
Reverts the ConditionalWeakTable<ITypeSymbol,...> interface-name cache: caching Roslyn symbols in persistent generator state is an anti-pattern (cross-compilation rooting risk), and AllInterfaces is already lazily cached on the symbol by Roslyn, so the win was marginal. The class no longer caches, so the name is corrected to InterfaceHelper. Keeps the real wins from this PR (single-pass attribute classification, FirstOrDefault/Enumerable.Repeat LINQ removals).
Snapshots unchanged.
[](/apps/claude)
thomhurst changed the title
perf(sourcegen): real InterfaceCache + single-pass attribute classification perf(sourcegen): Single-pass attribute classification
thomhurst deleted the perf/issue-6106-sourcegen-interfacecache branch
This was referenced
May 29, 2026
This was referenced
Jun 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})