Speed up at(size_type) and array-to-container conversion

Move the out_of_range message construction of at(size_type) and at(key)
into out-of-line, never-inlined helpers so the accessors inline like
operator[]. Convert JSON arrays into standard containers by looping over
the stored array_t and calling push_back (falling back to insert(end())
for containers without push_back, such as std::set) instead of
std::transform with std::inserter. Add benchmarks.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-14 22:18:42 +02:00
1 parent 4e294f4b18
commit 4b8213a5a3
4 files changed
+128 -18

No files matched your search

+50
View File
@@ -9,7 +9,10 @@
#include <benchmark/benchmark.h>
#include <nlohmann/json.hpp>
#include <fstream>
#include <array>
#include <deque>
#include <numeric>
#include <set>
#include <vector>
#include <test_data.hpp>
@@ -621,4 +624,51 @@ static void FromCborChunkedString(benchmark::State& state, const std::size_t chu
BENCHMARK_CAPTURE(FromCborChunkedString, 10000 chunks, 10000);
// checked element access (at(i) must inline like operator[])
static void ArrayAt(benchmark::State& state)
{
json j = json::array();
for (int i = 0; i < 1000; ++i)
{
j.push_back(i);
}
const json& cj = j;
for (auto _ : state)
{
std::int64_t sum = 0;
for (std::size_t i = 0; i < 1000; ++i)
{
sum += cj.at(i).get<int>();
}
benchmark::DoNotOptimize(sum);
}
state.SetItemsProcessed(state.iterations() * 1000);
}
BENCHMARK(ArrayAt);
// conversion of a JSON array into standard containers
template<typename Container>
static void GetArray(benchmark::State& state)
{
json j = json::array();
for (int i = 0; i < 1000; ++i)
{
j.push_back(i);
}
for (auto _ : state)
{
auto c = j.get<Container>();
benchmark::DoNotOptimize(c);
}
state.SetItemsProcessed(state.iterations() * 1000);
}
BENCHMARK_TEMPLATE(GetArray, std::vector<int>);
BENCHMARK_TEMPLATE(GetArray, std::deque<int>);
BENCHMARK_TEMPLATE(GetArray, std::set<int>);
BENCHMARK_TEMPLATE(GetArray, std::array<int, 1000>);
BENCHMARK_MAIN();