From 2ddee130c9547fe2a03d89a31400220daee942cf Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 1 Nov 2026 10:40:05 +0100 Subject: [PATCH] CBOR reader: inline get_cbor_float() and always inline get() instead The never-inlined get_cbor_float() costs a call for every float read from input without bulk access: reading canada.json from CBOR through a FILE* became 5.6 % slower on Apple clang in the benchmark suite. The helper existed only because GCC 13 stopped inlining the stream adapter's get_character() into parse_cbor_internal. Always inlining binary_reader::get() fixes that as well. callgrind, all binary formats on buffer, std::istringstream and FILE* input (canada and citm_catalog): GCC 13 0.986-1.003, GCC 16 0.994-1.006, Clang 23 identical. Apple clang suite: FromBinaryFile/cbor/canada 0.939, geomean of the 53 binary reader rows 0.998. Signed-off-by: Niels Lohmann --- include/nlohmann/detail/input/binary_reader.hpp | 9 ++++++--- single_include/nlohmann/json.hpp | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 37b1b0e18..7e3f3d088 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -1148,10 +1148,8 @@ class binary_reader } } - /// read a single- or double-precision float (kept out of - /// parse_cbor_value, which is inlined into parse_cbor_internal) + /// read a single- or double-precision float template - JSON_HEDLEY_NEVER_INLINE bool get_cbor_float() { NumberType number{}; @@ -4205,7 +4203,12 @@ class binary_reader `char_traits::eof()` in that case. @return character read from the input + + @note always inlined: GCC otherwise stops inlining the stream adapter's + get_character() into parse_cbor_internal once that function grows + (+0.45 % instructions for CBOR from a std::istringstream with GCC 13) */ + JSON_HEDLEY_ALWAYS_INLINE char_int_type get() { ++chars_read; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 884532424..6f9cd1b86 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -18925,10 +18925,8 @@ class binary_reader } } - /// read a single- or double-precision float (kept out of - /// parse_cbor_value, which is inlined into parse_cbor_internal) + /// read a single- or double-precision float template - JSON_HEDLEY_NEVER_INLINE bool get_cbor_float() { NumberType number{}; @@ -21982,7 +21980,12 @@ class binary_reader `char_traits::eof()` in that case. @return character read from the input + + @note always inlined: GCC otherwise stops inlining the stream adapter's + get_character() into parse_cbor_internal once that function grows + (+0.45 % instructions for CBOR from a std::istringstream with GCC 13) */ + JSON_HEDLEY_ALWAYS_INLINE char_int_type get() { ++chars_read;