Write the count of a UBJSON or BJData container in one reservation

With use_size, a container is announced by the marker `#` and its element
count as an integer, three small sink writes for the many containers of up to
127 elements (an empty array, an object with a few members).

A count of up to 127 is now written as `#`, `i` and one byte in a single
reservation.

Instructions per call (Linux, GCC 13, thousands), to_ubjson with use_size and use_type: canada 25813 -> 22060, citm_catalog 10656 -> 9192, 20000 small objects 18178 -> 16798; to_bjdata with use_size and use_type: canada 26341 -> 22588, citm_catalog 10904 -> 9440.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-22 09:29:24 +02:00
1 parent a3b9e9c712
commit 26b4716740
2 files changed
+38 -8

No files matched your search

@@ -1173,8 +1173,7 @@ class binary_writer
if (use_count)
{
oa.write_character(to_char_type('#'));
write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
write_ubjson_count(j.m_data.m_value.array->size(), use_bjdata);
}
return !use_count;
@@ -1213,8 +1212,7 @@ class binary_writer
if (use_count)
{
oa.write_character(to_char_type('#'));
write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
write_ubjson_count(j.m_data.m_value.object->size(), use_bjdata);
}
return !use_count;
@@ -3410,6 +3408,23 @@ class binary_writer
}
}
/// write the count marker `#` and the number of elements of a container as
/// an integer; a count of up to 127, which is `i` and a byte, in one reservation
void write_ubjson_count(const std::size_t count, const bool use_bjdata)
{
if (JSON_HEDLEY_LIKELY(count <= 127))
{
CharType* const out = oa.reserve(3);
out[0] = to_char_type('#');
out[1] = to_char_type('i');
out[2] = to_char_type(static_cast<std::uint8_t>(count));
oa.commit(3);
return;
}
oa.write_character(to_char_type('#'));
write_number_with_ubjson_prefix(count, true, use_bjdata);
}
/*!
@brief write a UBJSON/BJData string or object key: the optional string
marker `S`, the length as an integer with its marker, and the characters
+19 -4
View File
@@ -26023,8 +26023,7 @@ class binary_writer
if (use_count)
{
oa.write_character(to_char_type('#'));
write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
write_ubjson_count(j.m_data.m_value.array->size(), use_bjdata);
}
return !use_count;
@@ -26063,8 +26062,7 @@ class binary_writer
if (use_count)
{
oa.write_character(to_char_type('#'));
write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
write_ubjson_count(j.m_data.m_value.object->size(), use_bjdata);
}
return !use_count;
@@ -28260,6 +28258,23 @@ class binary_writer
}
}
/// write the count marker `#` and the number of elements of a container as
/// an integer; a count of up to 127, which is `i` and a byte, in one reservation
void write_ubjson_count(const std::size_t count, const bool use_bjdata)
{
if (JSON_HEDLEY_LIKELY(count <= 127))
{
CharType* const out = oa.reserve(3);
out[0] = to_char_type('#');
out[1] = to_char_type('i');
out[2] = to_char_type(static_cast<std::uint8_t>(count));
oa.commit(3);
return;
}
oa.write_character(to_char_type('#'));
write_number_with_ubjson_prefix(count, true, use_bjdata);
}
/*!
@brief write a UBJSON/BJData string or object key: the optional string
marker `S`, the length as an integer with its marker, and the characters