mirror of
https://github.com/nlohmann/json.git
synced 2026-10-25 07:18:55 +00:00
Reading: - layout_decimal() reads tokens of 16 to 19 digits 16 bytes at a time (NEON / SSE2) and layout_float() sends them to Eisel-Lemire directly, without the fast-path check that mixed data mispredicts. Dump (AArch64 only): - Fixed-notation tokens of 16 or 17 digits are converted in batches ahead of the walk, one loop per step: digits, Eisel-Lemire, and an exact 8.56 fixed-point choice of the shortest digits (shortest_token_digits(), in place of Zmij for these tokens). The output is the token with its last eight digits replaced. On x86-64 (Haswell, GCC 13 / Clang 18) the batch was not faster, so it is not used there. - Output is byte-identical to the previous writer: 10^9 generated tokens on M1 (all exponents, subnormals, 15-18 digits, exact binary fractions, near-short decimals) and 2.5 * 10^8 on x86-64, plus canada, twitter and citm_catalog in compact, indented, and ensure_ascii form. compare.py --download, M1 Max, clang 21, 30 rounds, two runs and aligned builds; json_view, and the factor of yyjson 0.13.0 over it: - canada dump 3636 -> 2597 us (0.47x -> 0.66x) - canada traverse 2300 -> 2059 us (0.85x -> 0.96x) - canada patch 4650 -> 3550 us (0.80x -> 1.05x) - canada update 4882 -> 3813 us (0.78x -> 1.00x) Linux x86-64 (umbrella, GCC 13): canada traverse 0.89x -> 0.95x, patch 0.98x -> 1.02x, update 0.96x -> 1.01x, dump 0.53x -> 0.57x. Open: the dump and traverse targets (>= 1.0x) are missed. The dump is bounded by the shortest-digits step (~8 ns per float, one multiply chain per float). Three rows are more than 1 % slower than before in both the plain and the aligned build, without a known cause (the parser's machine code is identical, and these documents do not use the new float path): - edit status patch +2.7 % (aligned +1.9 %) - edit citm_catalog update +1.7 % (aligned +1.5 %) - view jeopardy select +1.4 % (aligned +1.0 %) Signed-off-by: Niels Lohmann <mail@nlohmann.me>