mirror of
https://github.com/nlohmann/json.git
synced 2026-10-22 22:08:55 +00:00
Name BSON array elements without a std::string per element
BSON stores an array as a document whose keys are the decimal indices. Both passes built that key with std::to_string() and copied it into a string_t for every element, and the size pass then validated it like an object key (a search for U+0000 and the UTF-8 handler), though a decimal number cannot fail either. The index name now lives in the array's frame as digits that are incremented in place, and the size pass adds 2 + the number of digits. Instructions per call (Linux, GCC 13, thousands), to_bson: 20000 integers 16228 -> 6486, 20000 floats 16304 -> 6562, canada 109155 -> 55282, 20000 small objects 45513 -> 37171, citm_catalog 17269 -> 15026. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
2 files changed
+62
-42
No files matched your search
Generated
+31
-21
@@ -26439,30 +26439,43 @@ class binary_writer
|
||||
}
|
||||
}
|
||||
|
||||
/// make @ref index the next one: count it and update its decimal name
|
||||
void next_index() noexcept
|
||||
{
|
||||
++index;
|
||||
std::size_t i = index_name_size;
|
||||
while (i > 0)
|
||||
{
|
||||
--i;
|
||||
if (index_name[i] != '9')
|
||||
{
|
||||
++index_name[i];
|
||||
return;
|
||||
}
|
||||
index_name[i] = '0';
|
||||
}
|
||||
// all digits were 9: 10, 100, ...
|
||||
index_name[0] = '1';
|
||||
index_name[index_name_size++] = '0';
|
||||
}
|
||||
|
||||
/// the object or array
|
||||
const BasicJsonType* value;
|
||||
/// objects: the next member
|
||||
typename BasicJsonType::object_t::const_iterator member{};
|
||||
/// arrays: the index of the next element
|
||||
std::size_t index = 0;
|
||||
/// arrays: the name BSON gives that element, its decimal index (the
|
||||
/// index is at most 2^64 - 1, which has 20 digits)
|
||||
std::array<char, 20> index_name{{'0'}};
|
||||
/// arrays: the number of characters of @ref index_name
|
||||
std::size_t index_name_size = 1;
|
||||
/// @ref calc_bson_sizes only: where its size goes in the table
|
||||
std::size_t size_slot;
|
||||
/// @ref calc_bson_sizes only: the size of its entries seen so far
|
||||
std::size_t entries_size = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
@brief creates the name BSON gives the array element with index @a index
|
||||
@param[out] name receives the decimal index
|
||||
*/
|
||||
static void create_bson_index_name(const std::size_t index, string_t& name)
|
||||
{
|
||||
// the index is built as a std::string; convert explicitly, as the
|
||||
// two are only implicitly convertible for some string types
|
||||
const auto key = std::to_string(index);
|
||||
name = string_t(key.data(), key.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Calculates the size of every object and array in the BSON document
|
||||
@a document, including the document itself.
|
||||
@@ -26494,8 +26507,6 @@ class binary_writer
|
||||
// is in; nothing is allocated unless the document nests
|
||||
bson_frame current(&document);
|
||||
std::vector<bson_frame> parents;
|
||||
// string_t need not be default constructible
|
||||
string_t index_name("", 0);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -26526,9 +26537,10 @@ class binary_writer
|
||||
while (nested == nullptr && current.index < array.size())
|
||||
{
|
||||
const BasicJsonType& el = array[current.index];
|
||||
create_bson_index_name(current.index, index_name);
|
||||
current.entries_size += calc_bson_entry_header_size(index_name, el);
|
||||
++current.index;
|
||||
// the type, the decimal index (which is valid UTF-8 and
|
||||
// has no U+0000), and the terminating null byte
|
||||
current.entries_size += 2ul + current.index_name_size;
|
||||
current.next_index();
|
||||
if (el.is_structured())
|
||||
{
|
||||
nested = ⪙
|
||||
@@ -26583,8 +26595,6 @@ class binary_writer
|
||||
bson_frame current(&document);
|
||||
std::vector<bson_frame> parents;
|
||||
std::size_t next_size = 0;
|
||||
// string_t need not be default constructible
|
||||
string_t index_name("", 0);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -26615,8 +26625,8 @@ class binary_writer
|
||||
while (nested == nullptr && current.index < array.size())
|
||||
{
|
||||
const BasicJsonType& el = array[current.index];
|
||||
create_bson_index_name(current.index, index_name);
|
||||
++current.index;
|
||||
const string_t index_name(current.index_name.data(), current.index_name_size);
|
||||
current.next_index();
|
||||
if (el.is_structured())
|
||||
{
|
||||
write_bson_nested_head(index_name, el, nested_sizes[next_size++]);
|
||||
|
||||
Reference in new issue
Block a user