diff --git a/benchmarks/BUILD b/benchmarks/BUILD index 07207fc6c7..e219c42c80 100644 --- a/benchmarks/BUILD +++ b/benchmarks/BUILD @@ -87,7 +87,9 @@ cc_test( ":benchmark_descriptor_sv_cc_proto", ":benchmark_descriptor_upb_proto", ":benchmark_descriptor_upb_proto_reflection", + "//:base", "//:descriptor_upb_proto", + "//:mem", "//:reflection", "@com_github_google_benchmark//:benchmark_main", "@com_google_absl//absl/container:flat_hash_set", diff --git a/benchmarks/benchmark.cc b/benchmarks/benchmark.cc index 8ad30f0221..58e76f8b48 100644 --- a/benchmarks/benchmark.cc +++ b/benchmarks/benchmark.cc @@ -35,6 +35,8 @@ #include "benchmarks/descriptor.upb.h" #include "benchmarks/descriptor.upbdefs.h" #include "benchmarks/descriptor_sv.pb.h" +#include "upb/base/log2.h" +#include "upb/mem/arena.h" #include "upb/reflection/def.hpp" upb_StringView descriptor = benchmarks_descriptor_proto_upbdefinit.descriptor; @@ -73,6 +75,52 @@ static void BM_ArenaInitialBlockOneAlloc(benchmark::State& state) { } BENCHMARK(BM_ArenaInitialBlockOneAlloc); +static void BM_ArenaFuseUnbalanced(benchmark::State& state) { + std::vector arenas(state.range(0)); + size_t n = 0; + for (auto _ : state) { + for (auto& arena : arenas) { + arena = upb_Arena_New(); + } + for (auto& arena : arenas) { + upb_Arena_Fuse(arenas[0], arena); + } + for (auto& arena : arenas) { + upb_Arena_Free(arena); + } + n += arenas.size(); + } + state.SetItemsProcessed(n); +} +BENCHMARK(BM_ArenaFuseUnbalanced)->Range(2, 128); + +static void BM_ArenaFuseBalanced(benchmark::State& state) { + std::vector arenas(state.range(0)); + size_t n = 0; + + for (auto _ : state) { + for (auto& arena : arenas) { + arena = upb_Arena_New(); + } + + // Perform a series of fuses that keeps the halves balanced. + size_t max = upb_Log2Ceiling(arenas.size()); + for (size_t n = 0; n <= max; n++) { + size_t step = 1 << n; + for (size_t i = 0; i + step < arenas.size(); i += (step * 2)) { + upb_Arena_Fuse(arenas[i], arenas[i + step]); + } + } + + for (auto& arena : arenas) { + upb_Arena_Free(arena); + } + n += arenas.size(); + } + state.SetItemsProcessed(n); +} +BENCHMARK(BM_ArenaFuseBalanced)->Range(2, 128); + enum LoadDescriptorMode { NoLayout, WithLayout,