Skip to content

perf: drop a ~67 KiB duplicate prost decode tree + hoist a per-message traversal - #869

Merged
jlucaso1 merged 2 commits into
mainfrom
claude/whatsapp-rust-pr-review-mz0gyy
Jun 15, 2026
Merged

perf: drop a ~67 KiB duplicate prost decode tree + hoist a per-message traversal#869
jlucaso1 merged 2 commits into
mainfrom
claude/whatsapp-rust-pr-review-mz0gyy

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Two small, no-drawback perf cleanups found by auditing for binary bloat and per-message waste.

1. Binary: reuse the canonical buffer-type for MessageContextInfo merge (~67 KiB .text)

MessageUtils::encode_dm_plaintexts folds reporting context into a message's MessageContextInfo via ctx.merge(vec.as_slice()). The bare &[u8] buffer made prost monomorphize the entire MessageContextInfoBotMetadata decode subtree in a distinct buffer-type shape, separate from the &mut &mut &[u8] tree that Message::decode already instantiates — so the binary shipped a second copy of that subtree (BotMetadata::merge_field alone is ~51–67 KiB).

Fix: route through a pinned codec::message_context_info_merge that merges via &mut &mut &[u8], matching the shape the rest of the workspace decodes with (the waproto::codec module already exists for exactly this "pin one instantiation" purpose).

Verified locally with nm on the release artifact — each nested type drops from two merge_field copies to one:

symbol before after
BotMetadata::merge_field 2 copies (&mut &mut &[u8] + &[u8]) 1 (&mut &mut &[u8])
MessageContextInfo::merge_field 2 1
ContextInfo::merge_field 2 1

Same 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_message

On every inbound message, msg.get_base_message().get_ephemeral_expiration() was computed twice — once in the if condition, 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/clippy clean and the wacore message tests pass locally. Leaving the full suite + the binary-size CI report (which should show a .text decrease) + 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

Review in cubic

claude added 2 commits June 15, 2026 00:35
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.
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b9099f63-96e4-49c5-9671-35687f0a0a7b

📥 Commits

Reviewing files that changed from the base of the PR and between 9cfa4db and 4a0c4e9.

📒 Files selected for processing (3)
  • src/message/dispatch.rs
  • wacore/src/messages.rs
  • waproto/src/lib.rs

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Internal improvements to message expiration handling with simplified logic.
    • Enhanced message context information processing for better efficiency.
    • Optimized code organization and test-specific configurations.

Walkthrough

Adds message_context_info_merge to waproto::codec for merging protobuf bytes into an existing MessageContextInfo. wacore/src/messages.rs adopts this helper in encode_dm_plaintexts and moves the prost::Message import behind #[cfg(test)]. src/message/dispatch.rs simplifies ephemeral_expiration extraction to a single pattern match.

Changes

MessageContextInfo Merge Helper and Dispatch Cleanup

Layer / File(s) Summary
New message_context_info_merge codec helper and adoption
waproto/src/lib.rs, wacore/src/messages.rs
waproto::codec gains pub fn message_context_info_merge that merges protobuf bytes into an existing MessageContextInfo via prost. encode_dm_plaintexts switches from ctx.merge(...) to this new helper. The prost::Message import is scoped behind #[cfg(test)].
Ephemeral expiration pattern-match simplification
src/message/dispatch.rs
dispatch_parsed_message replaces the is_some() guard plus second get_ephemeral_expiration() call with a single let Some(exp) destructure, assigning via Arc::make_mut.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • oxidezap/whatsapp-rust#520: Directly overlaps with the Arc<MessageInfo>/Arc::make_mut-based ephemeral mutation refactor in dispatch_parsed_message — same function, same field.
  • oxidezap/whatsapp-rust#787: Both PRs touch MessageUtils::encode_dm_plaintexts in wacore/src/messages.rs around the message_context_info merge logic.
  • oxidezap/whatsapp-rust#842: The waproto::codec::message_context_info_merge helper introduced here is directly tied to the codec work from that PR.

Suggested labels

performance

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes both main performance improvements: binary bloat reduction via prost decode tree deduplication and the per-message ephemeral expiration traversal optimization.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, providing technical justification, verification details, and context for both performance improvements.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/whatsapp-rust-pr-review-mz0gyy

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@github-actions

Copy link
Copy Markdown

📦 Binary size report

Metric main PR Δ
bin size (stripped) 10.67 MiB 10.58 MiB -97.84 KiB (-0.90%) 🔽
bin .text 8.76 MiB 8.67 MiB -95.94 KiB (-1.07%) 🎉
bin allocated (text+data+bss) 10.67 MiB 10.58 MiB -96.00 KiB (-0.88%) 🔽
llvm-lines wacore 666,701 644,384 -22,317 (-3.35%) 🎉
llvm-lines wacore copies 18,047 17,673 -374 (-2.07%) 🎉
llvm-lines whatsapp-rust lib 652,742 652,742 0
llvm-lines whatsapp-rust lib copies 19,857 19,857 0
deps crates (Cargo.lock) 354 354 0
.text per crate
Crate main PR Δ
.text whatsapp_rust 1.47 MiB 1.47 MiB -760 B (-0.05%) 🔽
.text wacore 556.04 KiB 543.77 KiB -12.28 KiB (-2.21%) 🎉
.text wacore_binary 103.64 KiB 103.64 KiB 0
.text wacore_libsignal 168.32 KiB 168.32 KiB 0
.text wacore_appstate 35.26 KiB 35.26 KiB 0
.text wacore_noise 30.68 KiB 30.68 KiB 0
.text waproto 960.72 KiB 895.34 KiB -65.38 KiB (-6.81%) 🎉
.text whatsapp_rust_sqlite_storage 206.21 KiB 206.21 KiB 0
.text whatsapp_rust_tokio_transport 33.09 KiB 33.09 KiB 0
.text whatsapp_rust_ureq_http_client 6.19 KiB 6.19 KiB 0
.text std 1.13 MiB 1.13 MiB +72 B (+0.01%) 🔺
.text other deps 4.04 MiB 4.02 MiB -17.36 KiB (-0.42%) 🔽
Top movers (cargo-bloat attribution)
Crate main PR Δ
waproto 960.72 KiB 895.34 KiB -65.38 KiB (-6.81%)
prost 480.43 KiB 464.26 KiB -16.17 KiB (-3.37%)
wacore 556.04 KiB 543.77 KiB -12.28 KiB (-2.21%)
rustix 131 B 1.41 KiB +1.28 KiB (+1002.29%)
regex_automata 4.16 KiB 2.88 KiB -1.28 KiB (-30.81%)
bytes 7.74 KiB 6.55 KiB -1.19 KiB (-15.33%)

Baseline: 9cfa4dba3 (latest main run) · Head: 820c04e64 · Graphs

@codspeed-hq

codspeed-hq Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 172 untouched benchmarks


Comparing claude/whatsapp-rust-pr-review-mz0gyy (4a0c4e9) with main (9cfa4db)

Open in CodSpeed

@jlucaso1
jlucaso1 merged commit a725074 into main Jun 15, 2026
16 checks passed
@jlucaso1
jlucaso1 deleted the claude/whatsapp-rust-pr-review-mz0gyy branch June 15, 2026 00:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants