From 5cd24f618308932625f0571272288cb36debad08 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 2 Sep 2026 23:09:41 +0200 Subject: [PATCH] Benchmark parsing of pretty-printed JSON Every input in the benchmark corpus is minified or only lightly spaced, so none of them exercise the lexer's whitespace handling. Real-world JSON is frequently indented - configuration files, pretty-printed API responses, anything kept under version control - where the insignificant whitespace can outweigh the data itself. Add a ParseIndented family that re-serializes each document with an indentation and parses that. The content is identical to the matching ParseString row, so the pair isolates the cost of the whitespace alone. Measured here, parsing the indented form costs 16-34% more than the minified form of the same document, which nothing in the suite currently reports. Signed-off-by: Niels Lohmann --- tests/benchmarks/src/benchmarks.cpp | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/benchmarks/src/benchmarks.cpp b/tests/benchmarks/src/benchmarks.cpp index 4de238272..9522df5a4 100644 --- a/tests/benchmarks/src/benchmarks.cpp +++ b/tests/benchmarks/src/benchmarks.cpp @@ -81,6 +81,44 @@ BENCHMARK_CAPTURE(ParseString, signed_ints, TEST_DATA_DIRECTORY "/regressi BENCHMARK_CAPTURE(ParseString, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json"); BENCHMARK_CAPTURE(ParseString, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"); +////////////////////////////////////////////////////////////////////////////// +// parse pretty-printed JSON from string +// +// Every file in the corpus above is minified or only lightly spaced, so none of +// them exercise the lexer's whitespace handling. Real-world JSON is frequently +// indented - configuration files, pretty-printed API responses, anything kept +// under version control - where insignificant whitespace can outweigh the data. +// Re-serializing a document with an indentation and parsing that keeps the +// content identical to the ParseString row above, so the pair isolates the cost +// of the whitespace alone. +////////////////////////////////////////////////////////////////////////////// + +static void ParseIndented(benchmark::State& state, const char* filename, int indent) +{ + std::ifstream f(filename); + std::string str((std::istreambuf_iterator(f)), std::istreambuf_iterator()); + const std::string indented = json::parse(str).dump(indent); + + while (state.KeepRunning()) + { + state.PauseTiming(); + auto* j = new json(); + state.ResumeTiming(); + + *j = json::parse(indented); + + state.PauseTiming(); + delete j; + state.ResumeTiming(); + } + + state.SetBytesProcessed(state.iterations() * indented.size()); +} +BENCHMARK_CAPTURE(ParseIndented, jeopardy / 4, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json", 4); +BENCHMARK_CAPTURE(ParseIndented, canada / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json", 4); +BENCHMARK_CAPTURE(ParseIndented, citm_catalog / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", 4); +BENCHMARK_CAPTURE(ParseIndented, twitter / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", 4); + ////////////////////////////////////////////////////////////////////////////// // serialize JSON //////////////////////////////////////////////////////////////////////////////