Copy the tokens of a pointer without escapes straight into to_string()

to_string() appended a slash and every escaped token with library calls.
Tokens that contain neither '~' nor '/' (nearly all) are copied into a
string of the final size instead; the others are escaped as before.

json_pointer::to_string() over the keys of citm_catalog (instructions on macOS,
Linux Ir GCC 13 / Clang 18): 47.5M -> 30.6M, 33.6M -> 25.8M / 35.9M -> 22.8M;
twitter 18.8M -> 12.9M, 13.7M -> 11.2M / 14.5M -> 9.9M.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-22 09:30:56 +02:00
1 parent 2a2c7d30f0
commit eb2a092d70
2 files changed
+46

No files matched your search

+23
View File
@@ -82,12 +82,35 @@ class json_pointer
{
// one buffer: every token adds its escaped form (at least its length) and a slash
std::size_t length = 0;
bool plain = true;
for (const auto& reference_token : reference_tokens)
{
length += reference_token.size() + 1;
const char* const data = reference_token.data();
for (std::size_t i = 0, size = reference_token.size(); plain && i < size; ++i)
{
plain = data[i] != '~' && data[i] != '/';
}
}
string_t result;
if (JSON_HEDLEY_LIKELY(plain))
{
// nothing to escape: the tokens are copied into the string
result.resize(length);
if (length != 0)
{
char* out = &result[0];
for (const auto& reference_token : reference_tokens)
{
*out++ = '/';
std::memcpy(out, reference_token.data(), reference_token.size());
out += reference_token.size();
}
}
return result;
}
result.reserve(length);
for (const auto& reference_token : reference_tokens)
{
+23
View File
@@ -22432,12 +22432,35 @@ class json_pointer
{
// one buffer: every token adds its escaped form (at least its length) and a slash
std::size_t length = 0;
bool plain = true;
for (const auto& reference_token : reference_tokens)
{
length += reference_token.size() + 1;
const char* const data = reference_token.data();
for (std::size_t i = 0, size = reference_token.size(); plain && i < size; ++i)
{
plain = data[i] != '~' && data[i] != '/';
}
}
string_t result;
if (JSON_HEDLEY_LIKELY(plain))
{
// nothing to escape: the tokens are copied into the string
result.resize(length);
if (length != 0)
{
char* out = &result[0];
for (const auto& reference_token : reference_tokens)
{
*out++ = '/';
std::memcpy(out, reference_token.data(), reference_token.size());
out += reference_token.size();
}
}
return result;
}
result.reserve(length);
for (const auto& reference_token : reference_tokens)
{