perf: drop a ~67 KiB duplicate prost decode tree + hoist a per-message traversal - #869
Conversation
Folding reporting context into a message's MessageContextInfo went through `ctx.merge(vec.as_slice())`, whose `&[u8]` buffer made prost monomorphize the whole MessageContextInfo->BotMetadata decode subtree in a distinct buffer-type shape, separate from the `&mut &mut &[u8]` tree that `Message::decode` already instantiates. That duplicated ~67 KiB of .text (a second BotMetadata::merge_field copy alone). Route the merge through a pinned `codec::message_context_info_merge` that merges via `&mut &mut &[u8]`, matching the shape the rest of the workspace decodes with, so the nested tree is reused. Verified with nm: BotMetadata/MessageContextInfo/ ContextInfo merge_field each drop from two copies to one. Same merge semantics, cold path (only the rare top-level-mci splice case), no behavior change.
dispatch_parsed_message computed msg.get_base_message().get_ephemeral_expiration() twice on every inbound message (once to test, once to assign) — each call walks the wrapper levels and iterates the ~28-variant content list. Bind it once.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds ChangesMessageContextInfo Merge Helper and Dispatch Cleanup
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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 |
There was a problem hiding this comment.
No issues found across 3 files
Tip: cubic could auto-approve low-risk PRs like this, if it thinks it's safe to merge. Learn more
Re-trigger cubic
📦 Binary size report
.text per crate
Top movers (cargo-bloat attribution)
Baseline: |
Two small, no-drawback perf cleanups found by auditing for binary bloat and per-message waste.
1. Binary: reuse the canonical buffer-type for
MessageContextInfomerge (~67 KiB .text)MessageUtils::encode_dm_plaintextsfolds reporting context into a message'sMessageContextInfoviactx.merge(vec.as_slice()). The bare&[u8]buffer made prost monomorphize the entireMessageContextInfo→BotMetadatadecode subtree in a distinct buffer-type shape, separate from the&mut &mut &[u8]tree thatMessage::decodealready instantiates — so the binary shipped a second copy of that subtree (BotMetadata::merge_fieldalone is ~51–67 KiB).Fix: route through a pinned
codec::message_context_info_mergethat merges via&mut &mut &[u8], matching the shape the rest of the workspace decodes with (thewaproto::codecmodule already exists for exactly this "pin one instantiation" purpose).Verified locally with
nmon the release artifact — each nested type drops from twomerge_fieldcopies to one:BotMetadata::merge_field&mut &mut &[u8]+&[u8])&mut &mut &[u8])MessageContextInfo::merge_fieldContextInfo::merge_fieldSame merge semantics (later-set fields win); this is a cold path (only the rare case where the message already carries a top-level
message_context_info). No behavior change.2. Runtime: hoist a duplicated traversal in
dispatch_parsed_messageOn every inbound message,
msg.get_base_message().get_ephemeral_expiration()was computed twice — once in theifcondition, once in the assignment. Each call walks the wrapper levels and iterates the ~28-variant content list. Bind it once with a let-chain. Tiny, but pure waste on the hottest path.Both ran
cargo fmt/clippyclean and thewacoremessage tests pass locally. Leaving the full suite + the binary-size CI report (which should show a.textdecrease) + CodSpeed to CI.Context: this came out of a fresh audit after the appstate dedup PR (#868); the remaining heavy benchmarks are genuine crypto/zlib, so these target binary bloat and per-message overhead rather than a hot algorithmic loop.
Generated by Claude Code