From 0c1da0a713c6d9771065aa85d29958e14780d63b Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Thu, 3 Jun 2021 11:46:34 +0300 Subject: [PATCH] Make 'complexity reports' cache per-family, not global (#1166) While the current variant works, it assumes that all the instances of a single family will be run together, with nothing inbetween them. Naturally, that won't work once the runs may be interleaved. --- src/benchmark.cc | 16 ++++++++++++---- src/benchmark_runner.cc | 19 ++++++++++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/benchmark.cc b/src/benchmark.cc index d205232b..cf24ffdc 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -265,8 +265,9 @@ void RunBenchmarks(const std::vector& benchmarks, BenchmarkReporter::Context context; context.name_field_width = name_field_width; - // Keep track of running times of all instances of current benchmark - std::vector complexity_reports; + // Keep track of running times of all instances of each benchmark family. + std::map> + complexity_reports; // We flush streams after invoking reporter methods that write to them. This // ensures users get timely updates even when streams are not line-buffered. @@ -281,8 +282,15 @@ void RunBenchmarks(const std::vector& benchmarks, flushStreams(display_reporter); flushStreams(file_reporter); - for (const auto& benchmark : benchmarks) { - RunResults run_results = RunBenchmark(benchmark, &complexity_reports); + for (const BenchmarkInstance& benchmark : benchmarks) { + std::vector* complexity_reports_for_family = + nullptr; + if (benchmark.complexity() != oNone) + complexity_reports_for_family = + &complexity_reports[benchmark.family_index()]; + + RunResults run_results = + RunBenchmark(benchmark, complexity_reports_for_family); auto report = [&run_results](BenchmarkReporter* reporter, bool report_aggregates_only) { diff --git a/src/benchmark_runner.cc b/src/benchmark_runner.cc index a9ff55c4..4869aa7b 100644 --- a/src/benchmark_runner.cc +++ b/src/benchmark_runner.cc @@ -142,10 +142,11 @@ class BenchmarkRunner { BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_, std::vector* complexity_reports_) : b(b_), - complexity_reports(*complexity_reports_), - min_time(!IsZero(b.min_time()) ? b.min_time() : FLAGS_benchmark_min_time), + complexity_reports(complexity_reports_), + min_time(!IsZero(b.min_time()) ? b.min_time() + : FLAGS_benchmark_min_time), repeats(b.repetitions() != 0 ? b.repetitions() - : FLAGS_benchmark_repetitions), + : FLAGS_benchmark_repetitions), has_explicit_iteration_count(b.iterations() != 0), pool(b.threads() - 1), iters(has_explicit_iteration_count ? b.iterations() : 1), @@ -178,12 +179,12 @@ class BenchmarkRunner { run_results.aggregates_only = ComputeStats(run_results.non_aggregates); // Maybe calculate complexity report - if ((b.complexity() != oNone) && b.last_benchmark_instance) { - auto additional_run_stats = ComputeBigO(complexity_reports); + if (complexity_reports && b.last_benchmark_instance) { + auto additional_run_stats = ComputeBigO(*complexity_reports); run_results.aggregates_only.insert(run_results.aggregates_only.end(), additional_run_stats.begin(), additional_run_stats.end()); - complexity_reports.clear(); + complexity_reports->clear(); } } @@ -193,7 +194,7 @@ class BenchmarkRunner { RunResults run_results; const benchmark::internal::BenchmarkInstance& b; - std::vector& complexity_reports; + std::vector* complexity_reports; const double min_time; const int repeats; @@ -360,8 +361,8 @@ class BenchmarkRunner { CreateRunReport(b, i.results, memory_iterations, memory_result, i.seconds, repetition_index, repeats); - if (!report.error_occurred && b.complexity() != oNone) - complexity_reports.push_back(report); + if (complexity_reports && !report.error_occurred) + complexity_reports->push_back(report); run_results.non_aggregates.push_back(report); }