bench(integration): cut CodSpeed variance with a fixed 2-worker runtime + deterministic allocator - #902
Conversation
…me + deterministic allocator The integration benches only run CodSpeed's Valgrind simulation+memory instruments, which serialize threads onto a single core. A multi-thread runtime therefore bought no measurable signal, only variance: its worker count tracked the runner's CPU count, so thread-stack memory and scheduling differed per runner (feeding the "different runtime environments" noise on send_message[20]). Switch to a current-thread runtime; the client has no block_in_place, so it drives fine and the scheduling becomes deterministic. Add a bench-only #[global_allocator] whose realloc always allocates a fresh block and copies instead of growing in place. In-place growth depends on the live heap layout, which varies run-to-run and was charged to the memory instrument as noise (send_and_receive[20]). Both follow CodSpeed's reducing-variance guide; production keeps the system allocator and runtime. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014VC9pPVwJqgcic3KEn4y98
📝 WalkthroughWalkthroughThe integration benchmark harness adds a ChangesBenchmark Infrastructure: Deterministic Allocator and Fixed Tokio Runtime
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📦 Binary size report
.text per crate
Top movers (cargo-bloat attribution)
Baseline: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 216e0caf00
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…rent-thread current_thread froze the background event drainers (connect_warmed_pair) between divan samples: spawned tasks only progress inside block_on, so receipts and delivered messages arriving after a measured send leaked into the next sample, regressing the cross-sample isolation the drainers provide (flagged by Codex on this PR). Pin a fixed 2-worker multi-thread runtime instead: its worker threads keep draining continuously between samples, while the fixed count stays independent of the runner's CPU count -- the per-runner thread-count variance the original switch was meant to remove. The deterministic allocator is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014VC9pPVwJqgcic3KEn4y98
Merging this PR will improve performance by 16.5%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Memory | send_message[20] |
38.8 KB | 32.3 KB | +20.06% |
| ⚡ | Memory | send_and_receive[1] |
13.6 KB | 12 KB | +13.05% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing claude/happy-newton-h0nk9d (738bdcb) with main (d252c7c)
Motivation
The integration benchmarks show run-to-run variance and trip CodSpeed's "Different runtime environments detected" warning (seen on #901, where
send_and_receive[20]Memory andsend_message[20]Simulation moved with no real code cause). This applies two techniques from CodSpeed's reducing-variance and regression-causes guides, both scoped to the bench binary only — production code is untouched.Changes
Fixed-size multi-thread runtime. The default multi-thread runtime sizes its worker pool to the runner's CPU count, so thread-stack memory and scheduling varied per runner — a source of the cross-environment noise. The shared runtime is now pinned to a fixed
worker_threads(2), making the benches runner-independent.Deterministic global allocator (bench-only). Added a
#[global_allocator]whosereallocalways allocates a fresh block and copiesmin(old, new)bytes instead of growing in place. Whether the system allocator can grow in place depends on the live heap layout, which varies run-to-run and was charged to the memory instrument as noise. Production keeps the system allocator.Expected effect
One-time re-baseline: the deterministic allocator may make the Memory number slightly higher but stable (the alloc+copy
reallochas a transient old+new peak). After that step, variance should drop.Validation
cargo clippy -p bench-integration --benchesandcargo fmtclean.Run CodSpeed integration benchmarksjob passes — the client drives fine on the pinned runtime.Out of scope (deferred)
Synchronous event draining in unmeasured setup (an alternative to the fixed pool), pinning the
bartendermock image to a digest, and evaluating a dedicated CodSpeed runner — the last is the actual root cause of the cross-environment warning but is an infra/cost decision.