Skip to content

descriptor: resolve each stored field once in DynamicMessage::for_each_set - #439

Open
serhiy-bzhezytskyy wants to merge 1 commit into
anthropics:mainfrom
serhiy-bzhezytskyy:descriptor/for-each-set-single-lookup
Open

descriptor: resolve each stored field once in DynamicMessage::for_each_set#439
serhiy-bzhezytskyy wants to merge 1 commit into
anthropics:mainfrom
serhiy-bzhezytskyy:descriptor/for-each-set-single-lookup

Conversation

@serhiy-bzhezytskyy

Copy link
Copy Markdown

Item 1 of #432.

What changed

  • for_each_set applies the presence rule to the value it is already holding instead of calling has(fd), which looked the same field number up in the field map a second time (buffa-descriptor/src/reflect/dynamic.rs:1650-1663 on 053fcf3; in debug builds has also re-resolved the descriptor for its membership assert).
  • The rule lives in one private helper, is_present(fd, value), used by both has and for_each_set; the comment that explained it moved with it.
  • Visited fields, their order and the ValueRefs handed to the callback are unchanged: has looked up fd.number(), and field_or_extension(number) returns the descriptor with exactly that number for declared fields and extensions alike, so it found the same value the loop holds.

Why

Per stored field the loop did a BTreeMap step, a descriptor lookup by number, and then a second BTreeMap lookup inside has for a value it already had. Measured on the benchmark datasets, for_each_set alone over pre-decoded messages, release build, 2,000 iterations × 3 runs, same binary on main and on this branch:

dataset set fields main, ns/field this branch, ns/field
AnalyticsEvent (50 messages) 250 10.3 – 11.3 6.2 – 6.5
GoogleMessage1 10 16.4 – 17.5 8.9 – 10.5

The existing reflect/*/dynamic_read_all criterion benches include the decode and move by less than their noise, so the isolated timing is the number. The probe is not part of this change.

Item 2 of the issue — a borrowing set_fields() iterator beside the trait method — is an API addition and is left for a separate change once its shape is decided.

Tests

  • dynamic_message_for_each_set_agrees_with_has: an implicit-presence scalar at its default (skipped) and non-default, an optional field at its default (visited), and a message field; asserts the visited set equals the set of fields for which has() is true, and equals [14, 16, 17].
  • cargo test -p buffa-descriptor --features reflect — 199 pass
  • cargo test -p buffa-test — 564 pass

Checks

  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo fmt --all --check
  • changelog fragment under .changes/unreleased/

Written with Claude Code.

…h_set

The loop resolved the field by number, then called `has`, which looked the
same number up in the field map again to apply the presence rule to a value
the loop already held. Apply the rule to that value through one helper shared
with `has`. Per set field: 10.3–11.3 ns → 6.2–6.5 ns (AnalyticsEvent),
16.4–17.5 → 8.9–10.5 (GoogleMessage1). Fixes anthropics#432 item 1; the borrowing
iterator in item 2 is a separate API addition.
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@serhiy-bzhezytskyy

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Sep 11, 2026
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