From f41f6408eb893d67290393e96d07fb64e0ccae48 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Fri, 16 Oct 2026 22:52:44 +0200 Subject: [PATCH] Write a MessagePack float that is not in an array of numbers into reserved space A float that was not part of a run in an array (an object member, a float in a mixed array) went through write_compact_float(), with a sink call for its marker and one through a std::array for its bytes. It is now encoded by the function that encodes the floats of a run, into space reserved from the sink. CBOR keeps the previous code for these floats: giving them the same treatment made GCC 13 stop inlining the encoder into the loop for the floats of an array, which cost 4 percent more instructions for canada and citm_catalog. Instructions per call (Linux, GCC 13, thousands), to_msgpack: 20000 small objects 14601 -> 13641. Signed-off-by: Niels Lohmann --- include/nlohmann/detail/output/binary_writer.hpp | 14 ++++++++++++-- single_include/nlohmann/json.hpp | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index 58d3ae41a..760ba271a 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -429,7 +429,7 @@ class binary_writer case value_t::number_float: { - write_compact_float(j.m_data.m_value.number_float, to_char_type(0xCA), to_char_type(0xCB)); + write_msgpack_float(j.m_data.m_value.number_float); break; } @@ -2899,6 +2899,13 @@ class binary_writer } } + /// write a float as MessagePack, into space reserved from the sink + JSON_HEDLEY_NEVER_INLINE + void write_msgpack_float(const number_float_t n) + { + oa.commit(encode_compact_float(oa.reserve(integer_encoding_space), n, to_char_type(0xCA), to_char_type(0xCB))); + } + /*! @brief write an object value (head and members) as MessagePack @@ -2931,6 +2938,10 @@ class binary_writer write_msgpack_integer(value, std::integral_constant()); break; + case value_t::number_float: + write_msgpack_float(value.m_data.m_value.number_float); + break; + case value_t::string: write_msgpack_string(*value.m_data.m_value.string, value); break; @@ -2938,7 +2949,6 @@ class binary_writer case value_t::object: case value_t::array: case value_t::binary: - case value_t::number_float: case value_t::discarded: default: write_msgpack(value, depth + 1); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 5b9bee5e0..2161e0390 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -25260,7 +25260,7 @@ class binary_writer case value_t::number_float: { - write_compact_float(j.m_data.m_value.number_float, to_char_type(0xCA), to_char_type(0xCB)); + write_msgpack_float(j.m_data.m_value.number_float); break; } @@ -27730,6 +27730,13 @@ class binary_writer } } + /// write a float as MessagePack, into space reserved from the sink + JSON_HEDLEY_NEVER_INLINE + void write_msgpack_float(const number_float_t n) + { + oa.commit(encode_compact_float(oa.reserve(integer_encoding_space), n, to_char_type(0xCA), to_char_type(0xCB))); + } + /*! @brief write an object value (head and members) as MessagePack @@ -27762,6 +27769,10 @@ class binary_writer write_msgpack_integer(value, std::integral_constant()); break; + case value_t::number_float: + write_msgpack_float(value.m_data.m_value.number_float); + break; + case value_t::string: write_msgpack_string(*value.m_data.m_value.string, value); break; @@ -27769,7 +27780,6 @@ class binary_writer case value_t::object: case value_t::array: case value_t::binary: - case value_t::number_float: case value_t::discarded: default: write_msgpack(value, depth + 1);