Repository navigation
perf(codegen): cache enum serializer emission per owner - #11645
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the per-owner enum serializer caching change.
No open issues 🎉
What changed in this PR
This PR adds per-owner caching for ordinary, source-declared, non-generic enum serializers, avoiding repeated syntax construction and formatting when their emission dependencies are unchanged. Other serializer shapes retain compilation-aware generation.
Changes:
- Introduces symbol-free enum emission plans and shares enum read/write rendering with the existing serializer path.
- Preserves current-compilation diagnostic locations and batches deduplicated outputs for add/remove/undo behavior.
- Includes the prerequisite lazy metadata-name formatting change and regression tests for caching, output parity, invalidation, and allocations.
| File | Description |
|---|---|
test/Orleans.CodeGenerator.Tests/ReferenceAssemblyModelExtractorTests.cs |
Tests metadata parity, shared names, and reduced formatting allocations. |
test/Orleans.CodeGenerator.Tests/EnumSerializerPlanTests.cs |
Tests enum caching, invalidation, fallback paths, and diagnostic freshness. |
src/Orleans.CodeGenerator/SourceGeneratorResults.cs |
Carries enum plans and includes diagnostic locations in equality and hashing. |
src/Orleans.CodeGenerator/SerializerGenerator.cs |
Uses the shared enum read/write renderer. |
src/Orleans.CodeGenerator/SerializableSourceOutputGenerator.cs |
Creates eligible enum emission plans during semantic extraction. |
src/Orleans.CodeGenerator/OrleansSourceGenerator.cs |
Adds per-owner enum caching and batched output registration. |
src/Orleans.CodeGenerator/Model/SerializableTypeModel.cs |
Clarifies discovery-model documentation and semantic dependencies. |
src/Orleans.CodeGenerator/Model/ReferenceAssemblyModelExtractor.cs |
Formats metadata type names on demand and reuses them. |
src/Orleans.CodeGenerator/Model/EnumSerializerPlan.cs |
Defines symbol-free serializer and output plans. |
src/Orleans.CodeGenerator/EnumSerializerGenerator.cs |
Implements enum plan creation and source rendering. |
Review effort: Balanced
Code coverage
Report-only conclusion: current-main baseline stale. The newest successful coverage run tested c28a6e9, not current main 03636bc. Coverage combines every CI test matrix job, including providers, CodeGen, .NET 8/10, Linux, Windows, and macOS, using canonical physical source and branch identities. The comparison remains report-only while normal line and branch variance is calibrated. Coverage details |
124310b to
1edd421
Compare
1edd421 to
fddaa43
Compare
Depends on #11633; this branch preserves the lazy-formatting parent ancestry. The intended fork-parent base is unavailable to app-native cross-fork PR creation, so the PR targets the established ultimate base,
dotnet/orleans:main. The unique enum layer is commit b34bd8b.Problem
Serializer source emission reconstructs symbol-based descriptions and emits every collected serializer whenever the compilation changes. Comparing complete generated files afterward preserves output equality but still pays for source construction and formatting.
Solution
Introduce complete, symbol-free emission plans for source-declared, non-generic enums with the ordinary integral-codec shape. Resolve all enum, underlying-codec, framework-type, accessibility, and output-identity dependencies against the current compilation, then cache syntax construction and formatting per enum owner. The existing serializer path shares the enum read/write renderer.
Keep diagnostics on their current-compilation path and include location identity in diagnostic equality/hash. Preserve add/remove/undo behavior on Roslyn 4.5 by retaining discovery ownership and registering the deduplicated output batch intact.
Retained-driver evidence distinguishes actual Cached work from Unchanged output: an unrelated method-body edit performs zero enum emitter executions (two Cached, zero Unchanged). Direct source construction/formatting for those two plans allocated approximately 373 KB on net8.0 and 339 KB on net10.0 in the focused runs; cached emission performs none of that construction. The remaining driver and compilation-validation work continues to allocate. These are retained-driver observations, not CLI compiler-server or wall-clock speedup claims.
Scope
This is the first complete enum-emission layer. DTOs, generic/hooked enum shapes, and referenced serializers retain compilation-aware generation. The broader DTO optimization requires complete member access/copyability, generic-constraint, base, constructor, hook, and reference-sensitive dependency plans; it remains a separate follow-up. Discovery scanning, proxy ownership, serializer-context/factory planning, wire IDs, and collision arbitration retain their existing mechanisms.
Microsoft Reviewers: Open in CodeFlow