Stop dump() from heap-allocating its output adapter per call (#5449)
* 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> * Take the output adapter by reference at the serializer ctor Per review: the serializer still holds the adapter as a non-owning pointer, but the constructor now takes output_adapter_protocol<char>& and takes its address internally, so every call site passes a reference. A reference cannot be null and reads as a borrow, which makes the lifetime contract harder to get wrong than handing over a raw pointer. The stored member and the write path are unchanged. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAYM1qhSA2FDaDcGfPW3fG Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Claude <noreply@anthropic.com> Signed-off-by: Niels Lohmann <mail@nlohmann.me> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
ff80ed3295
commit
da42a627dc
4 files changed
+24
-17
No files matched your search
@@ -62,7 +62,8 @@ 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] pretty_print_ whether the output shall be pretty-printed
|
||||
@param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII
|
||||
@@ -76,12 +77,12 @@ class serializer
|
||||
being threaded through every call to @ref dump, @ref dump_internal and
|
||||
@ref dump_iteratively.
|
||||
*/
|
||||
serializer(output_adapter_t<char> s, const char ichar,
|
||||
serializer(output_adapter_protocol<char>& s, const char ichar,
|
||||
const bool pretty_print_ = false,
|
||||
const bool ensure_ascii_ = false,
|
||||
const std::size_t indent_step_ = 0,
|
||||
error_handler_t error_handler_ = error_handler_t::strict)
|
||||
: o(std::move(s))
|
||||
: o(&s)
|
||||
, locale(std::localeconv())
|
||||
, indent_char(ichar)
|
||||
, pretty_print(pretty_print_)
|
||||
@@ -1678,8 +1679,8 @@ class serializer
|
||||
const char decimal_point;
|
||||
};
|
||||
|
||||
/// 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{{}};
|
||||
|
||||
Reference in new issue
Block a user