Skip to content

Commit 4c2e32f

Browse files
authored
Introduce "family index" field into JSON output (#1164)
It may be useful for those wishing to further post-process JSON results, but it is mainly geared towards better support for run interleaving, where results from the same family may not be close-by in the JSON. While we won't be able to do much about that for outputs, the tools can and perhaps should reorder the results to that at least in their output they are in proper order, not run order. Note that this only counts the families that were filtered-in, so if e.g. there were three families, and we filtered-out the second one, the two families (which were first and third) will have family indexes 0 and 1.
1 parent e0a080d commit 4c2e32f

17 files changed

Lines changed: 159 additions & 36 deletions

include/benchmark/benchmark.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,7 @@ class BenchmarkReporter {
14181418

14191419
std::string benchmark_name() const;
14201420
BenchmarkName run_name;
1421+
int64_t family_index;
14211422
RunType run_type;
14221423
std::string aggregate_name;
14231424
std::string report_label; // Empty if not set by benchmark.

src/benchmark_api_internal.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
namespace benchmark {
88
namespace internal {
99

10-
BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark,
10+
BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
1111
const std::vector<int64_t>& args,
1212
int thread_count)
1313
: benchmark_(*benchmark),
14+
family_index_(family_idx),
1415
aggregation_report_mode_(benchmark_.aggregation_report_mode_),
1516
args_(args),
1617
time_unit_(benchmark_.time_unit_),

src/benchmark_api_internal.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ namespace internal {
1717
// Information kept per benchmark we may want to run
1818
class BenchmarkInstance {
1919
public:
20-
BenchmarkInstance(Benchmark* benchmark, const std::vector<int64_t>& args,
21-
int threads);
20+
BenchmarkInstance(Benchmark* benchmark, int family_index,
21+
const std::vector<int64_t>& args, int threads);
2222

2323
const BenchmarkName& name() const { return name_; }
24+
int family_index() const { return family_index_; }
2425
AggregationReportMode aggregation_report_mode() const {
2526
return aggregation_report_mode_;
2627
}
@@ -45,6 +46,7 @@ class BenchmarkInstance {
4546
private:
4647
BenchmarkName name_;
4748
Benchmark& benchmark_;
49+
const int family_index_;
4850
AggregationReportMode aggregation_report_mode_;
4951
const std::vector<int64_t>& args_;
5052
TimeUnit time_unit_;

src/benchmark_register.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,12 @@ bool BenchmarkFamilies::FindBenchmarks(
129129
// Special list of thread counts to use when none are specified
130130
const std::vector<int> one_thread = {1};
131131

132+
int next_family_index = 0;
133+
132134
MutexLock l(mutex_);
133135
for (std::unique_ptr<Benchmark>& family : families_) {
136+
int family_index = next_family_index;
137+
134138
// Family was deleted or benchmark doesn't match
135139
if (!family) continue;
136140

@@ -154,13 +158,18 @@ bool BenchmarkFamilies::FindBenchmarks(
154158

155159
for (auto const& args : family->args_) {
156160
for (int num_threads : *thread_counts) {
157-
BenchmarkInstance instance(family.get(), args, num_threads);
161+
BenchmarkInstance instance(family.get(), family_index, args,
162+
num_threads);
158163

159164
const auto full_name = instance.name().str();
160165
if ((re.Match(full_name) && !isNegativeFilter) ||
161166
(!re.Match(full_name) && isNegativeFilter)) {
162167
instance.last_benchmark_instance = (&args == &family->args_.back());
163168
benchmarks->push_back(std::move(instance));
169+
170+
// Only bump the next family index once we've estabilished that
171+
// at least one instance of this family will be run.
172+
if (next_family_index == family_index) ++next_family_index;
164173
}
165174
}
166175
}

src/benchmark_runner.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ BenchmarkReporter::Run CreateRunReport(
7272
BenchmarkReporter::Run report;
7373

7474
report.run_name = b.name();
75+
report.family_index = b.family_index();
7576
report.error_occurred = results.has_error_;
7677
report.error_message = results.error_message_;
7778
report.report_label = results.report_label_;

src/complexity.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
193193
// Get the data from the accumulator to BenchmarkReporter::Run's.
194194
Run big_o;
195195
big_o.run_name = run_name;
196+
big_o.family_index = reports[0].family_index;
196197
big_o.run_type = BenchmarkReporter::Run::RT_Aggregate;
197198
big_o.repetitions = reports[0].repetitions;
198199
big_o.repetition_index = Run::no_repetition_index;
@@ -215,6 +216,7 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
215216
// Only add label to mean/stddev if it is same for all runs
216217
Run rms;
217218
rms.run_name = run_name;
219+
rms.family_index = reports[0].family_index;
218220
rms.run_type = BenchmarkReporter::Run::RT_Aggregate;
219221
rms.aggregate_name = "RMS";
220222
rms.report_label = big_o.report_label;

src/json_reporter.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ void JSONReporter::PrintRunData(Run const& run) {
207207
std::string indent(6, ' ');
208208
std::ostream& out = GetOutputStream();
209209
out << indent << FormatKV("name", run.benchmark_name()) << ",\n";
210+
out << indent << FormatKV("family_index", run.family_index) << ",\n";
210211
out << indent << FormatKV("run_name", run.run_name.str()) << ",\n";
211212
out << indent << FormatKV("run_type", [&run]() -> const char* {
212213
switch (run.run_type) {

src/statistics.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ std::vector<BenchmarkReporter::Run> ComputeStats(
148148
// Get the data from the accumulator to BenchmarkReporter::Run's.
149149
Run data;
150150
data.run_name = reports[0].run_name;
151+
data.family_index = reports[0].family_index;
151152
data.run_type = BenchmarkReporter::Run::RT_Aggregate;
152153
data.threads = reports[0].threads;
153154
data.repetitions = reports[0].repetitions;

test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ TEST_ARGS = ["--benchmark_min_time=0.01"]
2020

2121
PER_SRC_TEST_ARGS = ({
2222
"user_counters_tabular_test.cc": ["--benchmark_counters_tabular=true"],
23+
"repetitions_test.cc": [" --benchmark_repetitions=3"],
2324
})
2425

2526
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")

test/complexity_test.cc

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ namespace {
1313
int CONCAT(dummy, __LINE__) = AddComplexityTest(__VA_ARGS__)
1414

1515
int AddComplexityTest(std::string test_name, std::string big_o_test_name,
16-
std::string rms_test_name, std::string big_o) {
16+
std::string rms_test_name, std::string big_o,
17+
int family_index) {
1718
SetSubstitutions({{"%name", test_name},
1819
{"%bigo_name", big_o_test_name},
1920
{"%rms_name", rms_test_name},
@@ -25,25 +26,29 @@ int AddComplexityTest(std::string test_name, std::string big_o_test_name,
2526
{{"^%bigo_name %bigo_str %bigo_str[ ]*$"},
2627
{"^%bigo_name", MR_Not}, // Assert we we didn't only matched a name.
2728
{"^%rms_name %rms %rms[ ]*$", MR_Next}});
28-
AddCases(TC_JSONOut, {{"\"name\": \"%bigo_name\",$"},
29-
{"\"run_name\": \"%name\",$", MR_Next},
30-
{"\"run_type\": \"aggregate\",$", MR_Next},
31-
{"\"repetitions\": %int,$", MR_Next},
32-
{"\"threads\": 1,$", MR_Next},
33-
{"\"aggregate_name\": \"BigO\",$", MR_Next},
34-
{"\"cpu_coefficient\": %float,$", MR_Next},
35-
{"\"real_coefficient\": %float,$", MR_Next},
36-
{"\"big_o\": \"%bigo\",$", MR_Next},
37-
{"\"time_unit\": \"ns\"$", MR_Next},
38-
{"}", MR_Next},
39-
{"\"name\": \"%rms_name\",$"},
40-
{"\"run_name\": \"%name\",$", MR_Next},
41-
{"\"run_type\": \"aggregate\",$", MR_Next},
42-
{"\"repetitions\": %int,$", MR_Next},
43-
{"\"threads\": 1,$", MR_Next},
44-
{"\"aggregate_name\": \"RMS\",$", MR_Next},
45-
{"\"rms\": %float$", MR_Next},
46-
{"}", MR_Next}});
29+
AddCases(
30+
TC_JSONOut,
31+
{{"\"name\": \"%bigo_name\",$"},
32+
{"\"family_index\": " + std::to_string(family_index) + ",$", MR_Next},
33+
{"\"run_name\": \"%name\",$", MR_Next},
34+
{"\"run_type\": \"aggregate\",$", MR_Next},
35+
{"\"repetitions\": %int,$", MR_Next},
36+
{"\"threads\": 1,$", MR_Next},
37+
{"\"aggregate_name\": \"BigO\",$", MR_Next},
38+
{"\"cpu_coefficient\": %float,$", MR_Next},
39+
{"\"real_coefficient\": %float,$", MR_Next},
40+
{"\"big_o\": \"%bigo\",$", MR_Next},
41+
{"\"time_unit\": \"ns\"$", MR_Next},
42+
{"}", MR_Next},
43+
{"\"name\": \"%rms_name\",$"},
44+
{"\"family_index\": " + std::to_string(family_index) + ",$", MR_Next},
45+
{"\"run_name\": \"%name\",$", MR_Next},
46+
{"\"run_type\": \"aggregate\",$", MR_Next},
47+
{"\"repetitions\": %int,$", MR_Next},
48+
{"\"threads\": 1,$", MR_Next},
49+
{"\"aggregate_name\": \"RMS\",$", MR_Next},
50+
{"\"rms\": %float$", MR_Next},
51+
{"}", MR_Next}});
4752
AddCases(TC_CSVOut, {{"^\"%bigo_name\",,%float,%float,%bigo,,,,,$"},
4853
{"^\"%bigo_name\"", MR_Not},
4954
{"^\"%rms_name\",,%float,%float,,,,,,$", MR_Next}});
@@ -82,15 +87,15 @@ const char *lambda_big_o_1 = "f\\(N\\)";
8287

8388
// Add enum tests
8489
ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
85-
enum_big_o_1);
90+
enum_big_o_1, /*family_index=*/0);
8691

8792
// Add auto enum tests
8893
ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
89-
auto_big_o_1);
94+
auto_big_o_1, /*family_index=*/1);
9095

9196
// Add lambda tests
9297
ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
93-
lambda_big_o_1);
98+
lambda_big_o_1, /*family_index=*/2);
9499

95100
// ========================================================================= //
96101
// --------------------------- Testing BigO O(N) --------------------------- //
@@ -137,11 +142,11 @@ const char *lambda_big_o_n = "f\\(N\\)";
137142

138143
// Add enum tests
139144
ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name,
140-
enum_auto_big_o_n);
145+
enum_auto_big_o_n, /*family_index=*/3);
141146

142147
// Add lambda tests
143148
ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name,
144-
lambda_big_o_n);
149+
lambda_big_o_n, /*family_index=*/4);
145150

146151
// ========================================================================= //
147152
// ------------------------- Testing BigO O(N*lgN) ------------------------- //
@@ -178,11 +183,13 @@ const char *lambda_big_o_n_lg_n = "f\\(N\\)";
178183

179184
// Add enum tests
180185
ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name,
181-
rms_o_n_lg_n_test_name, enum_auto_big_o_n_lg_n);
186+
rms_o_n_lg_n_test_name, enum_auto_big_o_n_lg_n,
187+
/*family_index=*/6);
182188

183189
// Add lambda tests
184190
ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name,
185-
rms_o_n_lg_n_test_name, lambda_big_o_n_lg_n);
191+
rms_o_n_lg_n_test_name, lambda_big_o_n_lg_n,
192+
/*family_index=*/7);
186193

187194
// ========================================================================= //
188195
// -------- Testing formatting of Complexity with captured args ------------ //
@@ -204,7 +211,7 @@ const std::string complexity_capture_name =
204211
"BM_ComplexityCaptureArgs/capture_test";
205212

206213
ADD_COMPLEXITY_CASES(complexity_capture_name, complexity_capture_name + "_BigO",
207-
complexity_capture_name + "_RMS", "N");
214+
complexity_capture_name + "_RMS", "N", /*family_index=*/9);
208215

209216
// ========================================================================= //
210217
// --------------------------- TEST CASES END ------------------------------ //

0 commit comments

Comments
 (0)