Compare commits

..
Author SHA1 Message Date
Niels Lohmann 40a14c4ed8 Move the scanned string into the value instead of copying it
The SAX interface documents that the string handed to json_sax::string() may
be moved from, and the DOM handlers already move the one handed to binary().
string() did not, so every string value was copy-constructed out of the
lexer's token buffer, which then kept the buffer alive at its high-water mark
until the next token overwrote it.

Moving hands that buffer to the new value instead. The allocation count is
unchanged - the value needed one either way - but the copy is gone.

  jeopardy      247.3 ms -> 240.9 ms  (-2.6%)
  citm_catalog    4.61 ms ->   4.48 ms (-2.8%)
  40k 30-char strings 7.80 ms -> 7.64 ms (-2.1%)

Note this deliberately does not extend to the object key. Moving the key
hands the lexer's buffer - sized for the largest token seen so far - to a key
that is usually short, so the next value has to grow a fresh buffer. Measured,
that costs 11.9% on a document of many small keys with longer values.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-03 07:42:17 +02:00
2 changed files with 10 additions and 4 deletions
+5 -2
View File
@@ -222,7 +222,9 @@ class json_sax_dom_parser
bool string(string_t& val)
{
handle_value(val);
// the interface allows moving the value (see json_sax::string), which
// hands the lexer's buffer to the new value instead of copying it
handle_value(std::move(val));
return true;
}
@@ -532,7 +534,8 @@ class json_sax_dom_callback_parser
bool string(string_t& val)
{
handle_value(val);
// see json_sax_dom_parser::string()
handle_value(std::move(val));
return true;
}
+5 -2
View File
@@ -10739,7 +10739,9 @@ class json_sax_dom_parser
bool string(string_t& val)
{
handle_value(val);
// the interface allows moving the value (see json_sax::string), which
// hands the lexer's buffer to the new value instead of copying it
handle_value(std::move(val));
return true;
}
@@ -11049,7 +11051,8 @@ class json_sax_dom_callback_parser
bool string(string_t& val)
{
handle_value(val);
// see json_sax_dom_parser::string()
handle_value(std::move(val));
return true;
}