codegen: inline view field decoding#312
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
iainmcgin
left a comment
There was a problem hiding this comment.
[claude code] Thanks for chasing this down and for the clean fix — the diagnosis in #298 was exactly right, and putting the attribute on the one concrete non-generic function in the eager view-decode path is the correct and sufficient boundary. Reviewed the change end to end: all 45 generated merge_view_field impls carry the attribute, #[inline] (hint) rather than inline(always) is the right call given the size of the DescriptorProto-scale match bodies, the codegen assertion catches a future removal, and lazy views correctly needed no change since their field match already lives inside a single generated function.
We also validated the fix independently on a dedicated bare-metal box (c7i.metal-24xl, criterion, main as baseline vs this branch), across the repo's decode_view benchmark suite:
| dataset | main | this PR | delta |
|---|---|---|---|
| google_message1_proto3 | 364.1 ns | 246.0 ns | −32.5% |
| mesh | 5.446 ms | 3.916 ms | −28.1% |
| log_record | 22.08 µs | 17.84 µs | −19.3% |
| api_response | 6.453 µs | 5.459 µs | −15.7% |
| media_frame | 12.02 µs | 10.73 µs | −10.6% |
| analytics_event | 681.8 µs | 618.5 µs | −9.3% |
| packed_tile | 1.306 ms | 1.211 ms | −7.3% |
| packed_signed | 95.33 µs | 95.00 µs | −0.4% |
The owned decode control rows (which this change does not touch) stayed within the box's ±5% floor, so the gains above are the real effect. packed_signed sitting at ~0% is the expected null — that shape is dominated by packed varint runs, where per-element decode work rather than per-field dispatch is the cost. So the improvement generalises well beyond the MVT workload in #298, and is larger on shapes with many small nested messages, where the per-field call boundary dominated most.
One note for anyone reproducing this: the bench crate's default [profile.bench] (lto = true, codegen-units = 1) hides the effect entirely, because fat LTO grants the cross-CGU inlining that this attribute exists to grant. The numbers above were measured with the downstream-realistic profile (lto = false, codegen-units = 16), which is the regime a normal consumer builds in and the one #298 was measured under.
Approving — thank you for the contribution.
What this does
#[inline]on generatedMessageView::merge_view_fieldimplementationsCloses #298.
Why
The shared decode loop lives in
buffa, while each generated field match lives in the downstream crate. Without an inline hint, the split introduced a per-field cross-crate call on zero-copy view decoding. The benchmark reported in #298 measured 4.47 s on 0.8.1 and 4.17 s with this hint, recovering most of the regression against 0.7.1.RED → GREEN
Before the implementation, the focused test failed with:
After emitting the attribute, the same test passes:
Verification
cargo fmt --all --checkcargo clippy --workspace --all-targets -- -D warningscargo buildcargo test --workspaceRUSTDOCFLAGS='-D warnings' cargo doc --workspace --all-features --no-depsNo local performance benchmark was run; the timing above is the issue reporter's controlled measurement.