Skip to content

perf(client): reduce suspended OneWay state allocations - #796

Merged
SunSi12138 merged 2 commits into
devfrom
perf/729-oneway-core-split
Oct 9, 2026
Merged

SunSi12138 merged 2 commits into
devfrom
perf/729-oneway-core-split

Conversation

@SunSi12138

@SunSi12138 SunSi12138 commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Summary

Related to #729.

Split the existing internal OneWay async core into plain and streaming state machines after one descriptor check. Public/generated APIs and wrapper/lifecycle ownership stay unchanged.

This production PR contains only two files: the runtime change (+29 net lines) and two descriptor-shape regression cases. Tests verify producer ownership, wire flags, owned cancellation and pending/admission cleanup. Research infrastructure and experimental static-entry API B remain in unmerged Draft #795.

Allocation benefit

Hosted investigation 37945758812, using frozen A/C/B source 6ece2f7a and baseline 553854f5:

  • All 216 controlled and 108 tiered-PGO actual generated-invocation samples passed exact payload/frame/stream checks.
  • Paired C-minus-A process-allocation medians for suspended 0/1/2 streams: −48.024/−7.986/−8.165 B/op (12 pairs), and −47.957/−8.036/−8.276 B/op (six tiered pairs).
  • Every suspended pair improves. Synchronous caller allocations are essentially unchanged.
  • All C/A timing confidence intervals include 1. No latency improvement is claimed.
  • B has no justified incremental benefit over C, so its added API/generated-runtime compatibility cost is rejected.

Code-size tradeoff

Full-RPC 64-bit scalar/no-stream state shrinks 248→192 inline bytes; one/two-stream states 256/272→248/264 bytes. These are struct sizes, not heap-allocation measurements; the local fixture uses a different 32-bit request.

Aggregate MoveNext IL grows 1,781→2,078 B (+16.7%). In this six-shape fixture, NativeAOT executable size grows 25,072 B (+0.243%), and strict core native code grows 21,551→27,688 B (+28.5%). Individual executed bodies shrink but generic instantiations emit both branches; other contract catalogs can differ.

Validation and evidence

  • All 324 full-RPC service-completed cases passed: TCP/SharedMemory, JIT/NativeAOT, 0/1/2 streams, batch1/8, deadlines, cancellation, interceptors, telemetry, endpoints and admission.
  • This is one-round regression sanity, not statistical proof of zero regression or E2E acceleration. Median C/A wall ratios are 1.0013 JIT and 1.0010 AOT. Noisy outliers include +30.6% JIT TCP one-stream interceptor and +23.9% AOT SharedMemory two-stream interceptor; same-core B is near A in those cases.
  • Hosted environment: Ubuntu24.04 x64, .NET SDK10.0.112/runtime10.0.12.
  • Original archive SHA-256: 48c10e5d5244a715251be0bba1ae23ee7de435be96753e191f99adc0e28ecc89. Artifact-only recovery verified that digest and retained original raw rows/disassembly without rerunning measurements: 37950819696, 37951510883.
  • Independent review verified 763 recovered files, every raw pair, exact full-RPC completion, state layouts, API identity and native/JIT disassembly. Differential lifecycle checks passed 58 tests on A/C; 25 local C integration checks passed, with local SharedMemory permission-blocked before connection and covered successfully on GitHub.

Original investigation-head CI passed. Independent final review verified that two-file head a90c83db0c1c549e9e1352b1f8cdcc2f42df35b7 preserves the reviewed runtime/test blobs. This PR is Ready for review as requested by the owner; final-head CI continues in the background and is not represented as complete. Large Actions artifacts retain seven days; raw research evidence stays separate in #795, never in this production diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant