From fedb77dcdb42c7bade180be9eef99bae5028380e Mon Sep 17 00:00:00 2001 From: Googler Date: Tue, 7 Jul 2026 01:28:05 -0700 Subject: [PATCH] Use GetFieldArrayElement in AccessPath and add SetValueNested mutation in serde_benchmark. The benchmark now uses GetFieldArrayElement to directly access the first element of the "dataFeedElement" array, instead of first getting the entire array. This shows the speed improvement of using the direct element accessor. It also now adds a benchmark of a mutation of a large json object by adding an element to the end of an internal array and then popping it. PiperOrigin-RevId: 943741299 --- serde_json/serde_benchmark.cc | 37 ++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/serde_json/serde_benchmark.cc b/serde_json/serde_benchmark.cc index 20d330f..d2ba3fe 100644 --- a/serde_json/serde_benchmark.cc +++ b/serde_json/serde_benchmark.cc @@ -120,13 +120,40 @@ void BM_SerdeJson_AccessPath(benchmark::State& state, std::string json_document = LoadJson(json_file); SerdeJson parsed = gtl::ValueOrDie(SerdeJson::Parse(json_document)); for (auto s : state) { - std::vector elements = - gtl::ValueOrDie(parsed.GetFieldArray("dataFeedElement")); - std::string name = gtl::ValueOrDie(elements[0].GetFieldString("name")); + SerdeJson data_feed_element = + gtl::ValueOrDie(parsed.GetFieldArrayElement("dataFeedElement", 0)); + std::string name = + gtl::ValueOrDie(data_feed_element.GetFieldString("name")); benchmark::DoNotOptimize(name); } } +void BM_Nlohmann_SetValueNested(benchmark::State& state, + absl::string_view json_file) { + std::string json_document = LoadJson(json_file); + nlohmann::json parsed = nlohmann::json::parse(json_document); + for (auto s : state) { + parsed["dataFeedElement"].push_back("name"); + benchmark::DoNotOptimize(parsed); + parsed["dataFeedElement"].erase(parsed["dataFeedElement"].size() - 1); + } +} + +void BM_SerdeJson_SetValueNested(benchmark::State& state, + absl::string_view json_file) { + std::string json_document = LoadJson(json_file); + SerdeJson parsed = gtl::ValueOrDie(SerdeJson::Parse(json_document)); + SerdeJson name_val = gtl::ValueOrDie(SerdeJson::CreateString("name")); + for (auto s : state) { + std::vector array = + gtl::ValueOrDie(parsed.GetFieldArray("dataFeedElement")); + array.push_back(name_val); + benchmark::DoNotOptimize(parsed.AddFieldArray("dataFeedElement", array)); + array.pop_back(); + benchmark::DoNotOptimize(parsed.AddFieldArray("dataFeedElement", array)); + } +} + [[maybe_unused]] const bool kBenchmarkRegistration = [] { for (const auto& [benchmark_input_name, json_file] : std::initializer_list>{ @@ -153,6 +180,10 @@ void BM_SerdeJson_AccessPath(benchmark::State& state, BM_Nlohmann_AccessPath, "large.json"); benchmark::RegisterBenchmark("BM_SerdeJson_AccessPath_LargeDoc", BM_SerdeJson_AccessPath, "large.json"); + benchmark::RegisterBenchmark("BM_Nlohmann_SetValueNested_LargeDoc", + BM_Nlohmann_SetValueNested, "large.json"); + benchmark::RegisterBenchmark("BM_SerdeJson_SetValueNested_LargeDoc", + BM_SerdeJson_SetValueNested, "large.json"); return false; }();