Repository navigation
perf: cache interface identities and serialization dependencies - #11467
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
The implementation is focused, preserves public APIs, and has comprehensive targeted coverage.
0 open findings
What changed in this PR
Caches grain interface identities and resolves generated proxy copiers through provider-managed contracts to reduce proxy construction overhead.
Changes:
- Adds per-resolver interface identity caching.
- Generates provider-resolved
IDeepCopier<T>proxy fields. - Adds focused runtime, generator, concurrency, and documentation coverage.
| File | Description |
|---|---|
src/Orleans.Core/Manifest/GrainInterfaceTypeResolver.cs |
Caches successful interface identities. |
src/Orleans.CodeGenerator/ProxyGenerator.cs |
Resolves copier contracts through CodecProvider. |
test/Orleans.Core.Tests/Manifest/GrainInterfaceTypeResolverTests.cs |
Tests identity caching behavior. |
test/Orleans.Serialization.UnitTests/ProxyCopierResolutionTests.cs |
Tests copier reuse and resolution semantics. |
test/Orleans.CodeGenerator.Tests/ProxyCopierResolutionTests.cs |
Verifies generated copier contracts. |
test/Orleans.CodeGenerator.Tests/snapshots/OrleansSourceGeneratorTests.TestGrainComplexGrain.verified.cs |
Updates generated proxy snapshot. |
docs/site/src/content/docs/implementation/serialization.md |
Documents identity and copier caching. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Code coverage
Report-only conclusion: current-main baseline stale. The newest successful coverage run tested 4268237, not current main bfe0e81. 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 |
d50cd91 to
dfaa943
Compare


Grain-reference creation repeatedly formats interface identities and resolves serialization dependencies, adding work for each proxy instance.
Cache successful interface identities per resolver and CLR interface type, including exact closed generic arguments. The generated-code helper delegates built-in provider requests to
CodecProvider.GetService. Registered implementations use the provider's existing cache keyed by closed implementation type. Interface holders and other dependencies resolve throughServices, preserving construction-provider routing and external-DI restrictions inside closed factory graphs. Implementation activation remains private to the provider.Generated proxy fields and copier call sites retain their concrete types.
ProxyGeneratorand its existing snapshots match main. Ordinary dependency-injection lifetimes and serializer factory publication/failure semantics are preserved. The resolver cache remains unchanged from the original version of this PR.Review found a capturing construction lambda allocating 40 bytes even on cache hits. Construction state now lives in a static miss helper, and warm lookups precede manifest classification. Exact tests measure zero allocated bytes and zero dependency constructions for 1000 warm helper calls on .NET 8/10, with and without closed factories. Direct uncached activation of the tested generated copier allocates 32,096 bytes on .NET 10 and 64,096 bytes on .NET 8 while invoking 1000 constructors. Cached interface lookups allocate zero bytes versus 3,272,000 bytes for 1000 uncached convention lookups in the tested closed-generic workload. These are allocation measurements, not throughput claims.
The service cache retains completed implementations and dependency graphs for provider lifetime; the resolver retains entries for the distinct CLR interfaces it sees. Ordinary concurrent cold resolution can construct multiple candidates and returns the published instance. Closed factories retain their coordinated publication and failure semantics. The implementation reuses the existing service cache and construction machinery.
Behavioral coverage includes concrete reuse across providers, helper-first/provider-first resolution, closed generic proxies, shared references and cycles, override semantics, failure/retry, concurrent publication, and DI lifetimes. Closed-factory regressions exercise all six serialization holder contracts, provider interfaces, rollback after failure, and rejection of external DI before publication. The automated coverage comment describes superseded head
748d784080(83.39% whole-repository lines); current affected-code coverage remains pending refreshed CI.Originally extracted from
48f3aaa47fc18123db4109063af591f315e6f9cbthrough source9c1ef0f2feb258c1764de5f408d89c53e7e63f9f, then revised in review and rebased onto mainb3b76e2ab207f00e664e0167cd733800cd60379d. Public API signatures and serialization identities remain unchanged.Microsoft Reviewers: Open in CodeFlow