Repository navigation
Stop allocating the BJData excluded-marker list per container - #5555
Merged
Merged
Conversation
write_ubjson() built a std::vector of the eight markers BJData forbids as the type of an optimized container - one heap allocation plus a linear search for every array and object it wrote with use_type, even for plain UBJSON output, where the list isn't consulted. The list was also spelled out twice. A constexpr helper, is_bjdata_excluded_type_marker(), replaces both. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
gregmarr
approved these changes
Sep 24, 2026
5 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
write_ubjson()built astd::vectorof the eight markers BJData forbids as the type of an optimized container ([,{,S,H,T,F,N,Z). It did so for every array and object it wrote withuse_type, one heap allocation and a linear search each, even for plain UBJSON output, which never consults the list. The literal was also spelled out twice, kept in sync only by convention.The change
A
static constexprhelper,is_bjdata_excluded_type_marker(), replaces both vectors andstd::findcalls. It is the same set the reader rejects (bjd_optimized_type_markers), and nothing else changes.Verification
Byte-identical: a differential against
developover 28,400 outputs (22,720 of them UBJSON/BJData) is identical in C++11 and C++20. It coversjsonandordered_json, everyuse_size/use_typecombination, BJData drafts 2 and 3, and the vector and adapter overloads. A mutant that dropsSandZfrom the helper changes 2,203 of those outputs, so the differential does exercise it.unit-ubjsonandunit-bjdatapass. They build cleanly with CI's GCC warning flags in C++11 and C++26, and clang-tidy reports no new findings.Speed (clang
-O3, median of 41 runs, 20,000 small typed containers):developto_ubjson(j, true, true), arrays and objects of numbersto_bjdata(j, true, true), arrays and objects of numbersto_ubjson(j, true, true), arrays of stringsto_bjdata(j, true, true), arrays of strings#5518 moves both call sites into new functions; whichever of the two merges second needs a two-line adjustment.
Public API impact
No breaking changes. Same output, and only a private helper was added.
make amalgamate.🤖 Generated with Claude Code