mirror of
https://github.com/nlohmann/json.git
synced 2026-10-22 14:08:13 +00:00
Most strings in real documents are object keys and short values. For those, dump_escaped() scanned the bytes, called memcpy with a length known only at run time, and the surrounding quote, colon and space were three more bounds-checked writes. A string of up to 16 printable ASCII characters (no quote, backslash or DEL) is now read with two overlapping loads, checked with one SWAR test per word, and written together with its quotes and the colon with two overlapping stores. Anything else, and a write buffer without room, takes the general path unchanged. Little-endian targets only; others keep the general path. dump_scalar() held the code of every scalar type and saved and restored all callee-saved registers on every call. It only dispatches now, and the string, integer, float and binary writers are functions of their own, so each pays only for what it uses (the string path keeps the check for long strings in front of any attempt, which keeps documents of long strings neutral). Apple M1, Apple clang, retired instructions per dump(), on top of the printable-ASCII table of #5878: citm_catalog 7.54M -> 5.96M (-21 %) twitter 4.87M -> 4.40M (-10 %) jeopardy 603M -> 501M (-17 %) logs 8.65M -> 8.17M (-5 %) a 139-byte object 3497 -> 2997 (-14 %) signed_ints -4 %, canada -3 % Linux x86-64 (callgrind), the whole series against develop, gcc 13 / clang 18: citm_catalog -16 % / -19 % (compact), twitter -22 % / -24 %. Documents of long strings (paths, latin and CJK text) are within 1 %. Signed-off-by: Niels Lohmann <mail@nlohmann.me>