Suite, timeline endpoint, Appendix D and the scalar-run numbers now come from
develop b2674a4a2f with #5990, #5991, #5992, #5996, #5997, #5998, #5999 and
#6000 merged. The scalar runs are measured against a build without them on
develop's code, which no longer checks for a scalar before entering the loop.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
The baseline is now develop 9c349b1d7c with every open non-draft pull
request merged, including #5968, #5970, #5971, #5975, #5976, #5978,
#5979, #5980, #5981 and #5982. The suite was rerun on 11-01 with every
step repeated when the load rose above 5 while it ran; the comparison
with other libraries and the held-out files were rerun on 10-31.
- suite: 3.0x geometric mean (median 2.9x); Appendix B, the overview
and the distribution regenerated
- timeline endpoint, Appendix D and the cliffs figure updated
- the held-out figure compares json_document with the fastest other
library
- new paragraphs for the pull requests listed above
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
- short strings: two overlapping 16-byte loads and stores
- eight digits at a time: the three multiplications, lane by lane
- validate on the 19 held-out files, per file, Mac and x86-64
The prose the figures replace is trimmed.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
The suite (Appendix B, the short-version table, the overview and distribution
figures) and the timeline endpoint now measure develop d20c4dcd89 with #5964
and #5908 merged. The geometric mean stays 2.9x (2.95); Dump/signed_ints and
Dump/unsigned_ints gain 1.5x and 2.1x from #5964; GetVectorDouble/floats drops
from 10.3x to 7.0x because the old candidate's suite binary happened to compile
that loop faster (a standalone build takes 0.97 ms with both headers).
The timeline endpoint is the 10-27 value scaled by the ratio of the new to the
old candidate, both measured on 10-30, so that it stays comparable with the
other points of the timeline.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
The figures and Appendix E use the reruns with each library's fastest
modes. Skipping number conversion while reading is now allowed for
every library; copying number text is still not chosen when writing.
The text now says who set the rules, where libraries that check less
win select, how minified files change the picture, and that the
reused jeopardy.json claim holds with every library reused. A new
section covers 19 held-out files and JSONTestSuite, including where
json_document loses, and lists what was not measured. Every
comparison number was recomputed; Glaze is credited in the intro.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
- deeper technical detail and code in the eight themes; pull request
numbers move to the appendix, timeline steps are labelled by theme
- comparison with other libraries by use case, as heatmaps per
platform, with validation levels and the caveats next to the results
- appendix: test files, all 182 suite rows with a histogram, timeline
steps, algorithmic fixes, per-file tables, behaviour changes, setup,
pull requests by theme
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
- a dump workload in bench_all and bench_rs: each engine writes a
document parsed beforehand, and every output must read back with
bit-identical numbers; an optional argument selects one workload
- the post's comparison gains a write table, a throughput chart, a dump
row for all three configurations, and the x86-64 cases it loses
- the thanks section is split into adapted code and borrowed ideas
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
- caption every table and figure
- describe what makes twitter.json, citm_catalog.json, canada.json and
jeopardy.json hard, and what each timeline panel exercises
- split the json_view layout figure into the tree and the index, with
the example text above; fix the arrows into the string boxes
- arrows and a "less is better" axis label in the cliffs figure
- name nlohmann/json in the comparison tables and chart
- licenses of the adapted code in the thanks section
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Extends the comparison in "How 3.13.0 got faster" from yyjson, simdjson and
Boost.JSON to eleven engines: sonic-cpp, RapidJSON and Glaze (generic DOM,
lazy_json, reading into structs) in C++, sonic-rs, simd-json and serde_json in
Rust. Measured on an Apple M1 Max (Apple clang 21, Rust 1.99) and an x86-64
Haswell server (GCC 13, Clang 18). Every engine must return the same values,
string bytes and bit-identical number sums before it is timed.
The post now answers whether json_document is the fastest parser: it is the
fastest document parser at parse+dump everywhere and at parsing on Apple
silicon, ties with simdjson's DOM on x86-64, and loses to simdjson On-Demand
and Glaze structs when only a few fields are read.
tests/benchmarks/json_view/others holds the programs (bench_all.cpp, the Rust
crate with its Cargo.lock), summarize.py and the pinned versions and checksums.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
A post for the documentation (Home > Blog) on how 3.13.0 became faster:
eight themes with the pull requests behind them, the ideas taken from other
libraries, what did not work, how the fast paths are tested, and the
compile-time cost. Every number comes from a run on 2026-10-27 (3.12.0 against
develop plus the open non-draft PRs, Apple M1 Max) or from the linked PR.
- docs/mkdocs/docs/home/blog/how_3_13_0_got_faster.md: the post.
- docs/mkdocs/scripts/figures/perf_blog.py: draws its 12 figures (overview,
eight timeline panels, the SWAR test, the cliffs, json_view throughput) as
inline SVGs in the nj-charts style; data/perf_timeline.csv holds the
timeline.
- tests/benchmarks/history: history.cpp and history.py time one fixed program
against the header of every commit that changed it, interleaved, and write
one CSV row per commit with its PR. The timeline of the post comes from it.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>