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:
Claude
2026-09-10 19:00:23 +02:00
committed by Niels Lohmann
parent 772e44ff97
commit c5e2a95ff1
4 changed files with 24 additions and 17 deletions
+2 -1
View File
@@ -98,7 +98,8 @@ void check_escaped(const char* original, const char* escaped = "", bool ensure_a
void check_escaped(const char* original, const char* escaped, const bool ensure_ascii)
{
std::stringstream ss;
json::serializer s(nlohmann::detail::output_adapter<char>(ss), ' ', false, ensure_ascii);
nlohmann::detail::output_stream_adapter<char> adapter(ss);
json::serializer s(&adapter, ' ', false, ensure_ascii);
s.dump_escaped(original);
s.flush(); // dump_escaped writes into the serializer's internal buffer
CHECK(ss.str() == escaped);