mirror of
https://github.com/nlohmann/json.git
synced 2026-10-28 16:55:41 +00:00
GCC 13 compiled the ?: selections of token_digits_1/2(), biased_distance() and the batch's classification loop as branches. Their conditions are as good as random, so dumping canada.json mispredicted about one branch per float (callgrind --branch-sim: 220k per dump with GCC, 97k with Clang), and the dump took 21-26 % longer than with Clang. The selections are now masks (mask_if(), select_if()), which no compiler turns into a branch. canada.json dump on the Haswell VPS (dprobe, best of 60, 3 interleaved rounds): GCC 13 4.74-5.04 ms -> 3.98-4.24 ms, Clang 18 unchanged (3.93-4.06 -> 3.82-3.98 ms); mispredictions per dump 220k -> 98k with GCC. Instructions per dump: GCC 38.2M -> 40.2M, Clang 34.7M -> 35.0M. Apple M1 Max, Apple clang 21: 0.5-1.8 % fewer cycles per dump in 4 of 4 pairs. In bench_all, json_view's dump of canada.json against yyjson goes from 0.75-0.78 to 0.91 with GCC. Output unchanged: dump() equals json::parse(text).dump() for 4e7 random 16/17-digit, %.17g and short tokens (singles and pairs) with GCC 13 on x86-64 and 6e7 with Apple clang on arm64; unit-json_view_dump passes with GCC 13 and with Clang under ASan/UBSan. Signed-off-by: Niels Lohmann <mail@nlohmann.me>