mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
4d9d948627
The reflection deserializer used `obj[key].get(out.member)` per struct field, which delegates to find_field_unordered. For *absent* optional fields this scans the entire JSON object before returning NO_SUCH_FIELD — O(K) per absent optional, where K is the JSON object's field count. A struct with N optionals where most are absent pays O(N*K) per record. CITM hits this hard: CITMEvent has 7 optional fields; most events leave several of them null/missing, so we re-scan each event many times. Switch to single-pass dispatch when the struct has any std::optional member: walk the JSON object exactly once, dispatch each visited key to the matching struct member via a compile-time-generated key comparison (with length pre-filter), let object_iterator::operator++ auto-skip values for unknown keys. For structs with all-required fields (Twitter Status, User), keep the existing per-field obj[key] path. It's O(1) per field on in-order JSON and faster than the unrolled compare chain for dense, in-order objects. Measured (TRUE A/B, 7 alternating rounds, single docker invocation): CITM static_reflection: 2084 -> 2387 MB/s +14.5% CITM from: 2053 -> 2358 MB/s +14.9% Twitter static_reflection: 3416 -> 3419 MB/s break-even Twitter from: 3416 -> 3417 MB/s break-even All static_reflection_comprehensive_tests pass.