mirror of
https://github.com/nlohmann/json.git
synced 2026-09-01 05:57:14 +00:00
Stop dump() from heap-allocating its output adapter per call
The serializer held its output sink as output_adapter_t<char> (a std::shared_ptr<output_adapter_protocol<char>>), which dump() and operator<< built via make_shared -- one heap allocation per call for a sink that only wraps a reference to the caller's string or stream. Hold the sink as a non-owning output_adapter_protocol<char>* instead and construct the concrete adapter on the stack at the call site. The write path (o->write_characters) is unchanged, so output is byte-for-byte identical; a compact dump() of a small object drops from 2 heap allocations to 1 (only the returned string remains), ~3% faster. Completes the per-call allocation cleanup on this branch, which already removed the indent_string buffer (both were reported in #5413). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L1oJ2ggRHS37zeVe94QTA1 Signed-off-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -21043,13 +21043,14 @@ class serializer
|
||||
|
||||
public:
|
||||
/*!
|
||||
@param[in] s output stream to serialize to
|
||||
@param[in] s output adapter to serialize to; not owned by the serializer,
|
||||
so it must outlive it (it lives at the call site)
|
||||
@param[in] ichar indentation character to use
|
||||
@param[in] error_handler_ how to react on decoding errors
|
||||
*/
|
||||
serializer(output_adapter_t<char> s, const char ichar,
|
||||
serializer(output_adapter_protocol<char>* s, const char ichar,
|
||||
error_handler_t error_handler_ = error_handler_t::strict)
|
||||
: o(std::move(s))
|
||||
: o(s)
|
||||
, loc(std::localeconv())
|
||||
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
|
||||
, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
|
||||
@@ -22657,8 +22658,8 @@ class serializer
|
||||
}
|
||||
|
||||
private:
|
||||
/// the output of the serializer
|
||||
output_adapter_t<char> o = nullptr;
|
||||
/// the output of the serializer (non-owning; the adapter lives at the call site)
|
||||
output_adapter_protocol<char>* o = nullptr;
|
||||
|
||||
/// a (hopefully) large enough character buffer
|
||||
std::array<char, 64> number_buffer{{}};
|
||||
@@ -24360,7 +24361,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const error_handler_t error_handler = error_handler_t::strict) const
|
||||
{
|
||||
string_t result;
|
||||
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
|
||||
detail::output_string_adapter<char, string_t> string_adapter(result);
|
||||
serializer s(&string_adapter, indent_char, error_handler);
|
||||
|
||||
if (indent >= 0)
|
||||
{
|
||||
@@ -27074,7 +27076,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
o.width(0);
|
||||
|
||||
// do the actual serialization
|
||||
serializer s(detail::output_adapter<char>(o), o.fill());
|
||||
detail::output_stream_adapter<char> stream_adapter(o);
|
||||
serializer s(&stream_adapter, o.fill());
|
||||
s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
|
||||
return o;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user