@@ -69,35 +69,44 @@ int AddComplexityTest(const std::string &test_name,
69
69
70
70
void BM_Complexity_O1 (benchmark::State &state) {
71
71
for (auto _ : state) {
72
- for (int i = 0 ; i < 1024 ; ++i) {
73
- benchmark::DoNotOptimize (i);
72
+ // This test requires a non-zero CPU time to avoid divide-by-zero
73
+ benchmark::DoNotOptimize (state.iterations ());
74
+ double tmp = state.iterations ();
75
+ benchmark::DoNotOptimize (tmp);
76
+ for (benchmark::IterationCount i = 0 ; i < state.iterations (); ++i) {
77
+ benchmark::DoNotOptimize (state.iterations ());
78
+ tmp *= state.iterations ();
79
+ benchmark::DoNotOptimize (tmp);
74
80
}
81
+
82
+ // always 1ns per iteration
83
+ state.SetIterationTime (42 * 1e-9 );
75
84
}
76
85
state.SetComplexityN (state.range (0 ));
77
86
}
78
- BENCHMARK (BM_Complexity_O1)->Range(1 , 1 << 18 )->Complexity(benchmark::o1);
79
- BENCHMARK (BM_Complexity_O1)->Range(1 , 1 << 18 )->Complexity();
80
87
BENCHMARK (BM_Complexity_O1)
81
88
->Range(1 , 1 << 18 )
89
+ ->UseManualTime()
90
+ ->Complexity(benchmark::o1);
91
+ BENCHMARK (BM_Complexity_O1)->Range(1 , 1 << 18 )->UseManualTime()->Complexity();
92
+ BENCHMARK (BM_Complexity_O1)
93
+ ->Range(1 , 1 << 18 )
94
+ ->UseManualTime()
82
95
->Complexity([](benchmark::IterationCount) { return 1.0 ; });
83
96
84
- const char *one_test_name = " BM_Complexity_O1" ;
85
- const char *big_o_1_test_name = " BM_Complexity_O1_BigO" ;
86
- const char *rms_o_1_test_name = " BM_Complexity_O1_RMS" ;
87
- const char *enum_big_o_1 = " \\ ([0-9]+\\ )" ;
88
- // FIXME: Tolerate both '(1)' and 'lgN' as output when the complexity is auto
89
- // deduced.
90
- // See https://github.com/google/benchmark/issues/272
91
- const char *auto_big_o_1 = " (\\ ([0-9]+\\ ))|(lgN)|(N\\ ^2)" ;
97
+ const char *one_test_name = " BM_Complexity_O1/manual_time" ;
98
+ const char *big_o_1_test_name = " BM_Complexity_O1/manual_time_BigO" ;
99
+ const char *rms_o_1_test_name = " BM_Complexity_O1/manual_time_RMS" ;
100
+ const char *enum_auto_big_o_1 = " \\ ([0-9]+\\ )" ;
92
101
const char *lambda_big_o_1 = " f\\ (N\\ )" ;
93
102
94
103
// Add enum tests
95
104
ADD_COMPLEXITY_CASES (one_test_name, big_o_1_test_name, rms_o_1_test_name,
96
- enum_big_o_1 , /* family_index=*/ 0 );
105
+ enum_auto_big_o_1 , /* family_index=*/ 0 );
97
106
98
- // Add auto enum tests
107
+ // Add auto tests
99
108
ADD_COMPLEXITY_CASES (one_test_name, big_o_1_test_name, rms_o_1_test_name,
100
- auto_big_o_1 , /* family_index=*/ 1 );
109
+ enum_auto_big_o_1 , /* family_index=*/ 1 );
101
110
102
111
// Add lambda tests
103
112
ADD_COMPLEXITY_CASES (one_test_name, big_o_1_test_name, rms_o_1_test_name,
@@ -107,84 +116,102 @@ ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
107
116
// --------------------------- Testing BigO O(N) --------------------------- //
108
117
// ========================================================================= //
109
118
110
- std::vector<int > ConstructRandomVector (int64_t size) {
111
- std::vector<int > v;
112
- v.reserve (static_cast <size_t >(size));
113
- for (int i = 0 ; i < size; ++i) {
114
- v.push_back (static_cast <int >(std::rand () % size));
115
- }
116
- return v;
117
- }
118
-
119
119
void BM_Complexity_O_N (benchmark::State &state) {
120
- auto v = ConstructRandomVector (state.range (0 ));
121
- // Test worst case scenario (item not in vector)
122
- const int64_t item_not_in_vector = state.range (0 ) * 2 ;
123
120
for (auto _ : state) {
124
- auto it = std::find (v.begin (), v.end (), item_not_in_vector);
125
- benchmark::DoNotOptimize (it);
121
+ // This test requires a non-zero CPU time to avoid divide-by-zero
122
+ benchmark::DoNotOptimize (state.iterations ());
123
+ double tmp = state.iterations ();
124
+ benchmark::DoNotOptimize (tmp);
125
+ for (benchmark::IterationCount i = 0 ; i < state.iterations (); ++i) {
126
+ benchmark::DoNotOptimize (state.iterations ());
127
+ tmp *= state.iterations ();
128
+ benchmark::DoNotOptimize (tmp);
129
+ }
130
+
131
+ // 1ns per iteration per entry
132
+ state.SetIterationTime (state.range (0 ) * 42 * 1e-9 );
126
133
}
127
134
state.SetComplexityN (state.range (0 ));
128
135
}
129
136
BENCHMARK (BM_Complexity_O_N)
130
137
->RangeMultiplier(2 )
131
- ->Range(1 << 10 , 1 << 16 )
138
+ ->Range(1 << 10 , 1 << 20 )
139
+ ->UseManualTime()
132
140
->Complexity(benchmark::oN);
133
141
BENCHMARK (BM_Complexity_O_N)
134
142
->RangeMultiplier(2 )
135
- ->Range(1 << 10 , 1 << 16 )
143
+ ->Range(1 << 10 , 1 << 20 )
144
+ ->UseManualTime()
145
+ ->Complexity();
146
+ BENCHMARK (BM_Complexity_O_N)
147
+ ->RangeMultiplier(2 )
148
+ ->Range(1 << 10 , 1 << 20 )
149
+ ->UseManualTime()
136
150
->Complexity([](benchmark::IterationCount n) -> double {
137
151
return static_cast <double >(n);
138
152
});
139
- BENCHMARK (BM_Complexity_O_N)
140
- ->RangeMultiplier(2 )
141
- ->Range(1 << 10 , 1 << 16 )
142
- ->Complexity();
143
153
144
- const char *n_test_name = " BM_Complexity_O_N" ;
145
- const char *big_o_n_test_name = " BM_Complexity_O_N_BigO " ;
146
- const char *rms_o_n_test_name = " BM_Complexity_O_N_RMS " ;
154
+ const char *n_test_name = " BM_Complexity_O_N/manual_time " ;
155
+ const char *big_o_n_test_name = " BM_Complexity_O_N/manual_time_BigO " ;
156
+ const char *rms_o_n_test_name = " BM_Complexity_O_N/manual_time_RMS " ;
147
157
const char *enum_auto_big_o_n = " N" ;
148
158
const char *lambda_big_o_n = " f\\ (N\\ )" ;
149
159
150
160
// Add enum tests
151
161
ADD_COMPLEXITY_CASES (n_test_name, big_o_n_test_name, rms_o_n_test_name,
152
162
enum_auto_big_o_n, /* family_index=*/ 3 );
153
163
164
+ // Add auto tests
165
+ ADD_COMPLEXITY_CASES (n_test_name, big_o_n_test_name, rms_o_n_test_name,
166
+ enum_auto_big_o_n, /* family_index=*/ 4 );
167
+
154
168
// Add lambda tests
155
169
ADD_COMPLEXITY_CASES (n_test_name, big_o_n_test_name, rms_o_n_test_name,
156
- lambda_big_o_n, /* family_index=*/ 4 );
170
+ lambda_big_o_n, /* family_index=*/ 5 );
157
171
158
172
// ========================================================================= //
159
- // ------------------------- Testing BigO O(N*lgN ) ------------------------- //
173
+ // ------------------------- Testing BigO O(NlgN ) ------------------------- //
160
174
// ========================================================================= //
161
175
176
+ static const double kLog2E = 1.44269504088896340736 ;
162
177
static void BM_Complexity_O_N_log_N (benchmark::State &state) {
163
- auto v = ConstructRandomVector (state.range (0 ));
164
178
for (auto _ : state) {
165
- std::sort (v.begin (), v.end ());
179
+ // This test requires a non-zero CPU time to avoid divide-by-zero
180
+ benchmark::DoNotOptimize (state.iterations ());
181
+ double tmp = state.iterations ();
182
+ benchmark::DoNotOptimize (tmp);
183
+ for (benchmark::IterationCount i = 0 ; i < state.iterations (); ++i) {
184
+ benchmark::DoNotOptimize (state.iterations ());
185
+ tmp *= state.iterations ();
186
+ benchmark::DoNotOptimize (tmp);
187
+ }
188
+
189
+ state.SetIterationTime (state.range (0 ) * kLog2E * std::log (state.range (0 )) *
190
+ 42 * 1e-9 );
166
191
}
167
192
state.SetComplexityN (state.range (0 ));
168
193
}
169
- static const double kLog2E = 1.44269504088896340736 ;
170
194
BENCHMARK (BM_Complexity_O_N_log_N)
171
195
->RangeMultiplier(2 )
172
- ->Range(1 << 10 , 1 << 16 )
196
+ ->Range(1 << 10 , 1U << 24 )
197
+ ->UseManualTime()
173
198
->Complexity(benchmark::oNLogN);
174
199
BENCHMARK (BM_Complexity_O_N_log_N)
175
200
->RangeMultiplier(2 )
176
- ->Range(1 << 10 , 1 << 16 )
201
+ ->Range(1 << 10 , 1U << 24 )
202
+ ->UseManualTime()
203
+ ->Complexity();
204
+ BENCHMARK (BM_Complexity_O_N_log_N)
205
+ ->RangeMultiplier(2 )
206
+ ->Range(1 << 10 , 1U << 24 )
207
+ ->UseManualTime()
177
208
->Complexity([](benchmark::IterationCount n) {
178
209
return kLog2E * static_cast <double >(n) * std::log (static_cast <double >(n));
179
210
});
180
- BENCHMARK (BM_Complexity_O_N_log_N)
181
- ->RangeMultiplier(2 )
182
- ->Range(1 << 10 , 1 << 16 )
183
- ->Complexity();
184
211
185
- const char *n_lg_n_test_name = " BM_Complexity_O_N_log_N" ;
186
- const char *big_o_n_lg_n_test_name = " BM_Complexity_O_N_log_N_BigO " ;
187
- const char *rms_o_n_lg_n_test_name = " BM_Complexity_O_N_log_N_RMS " ;
212
+ const char *n_lg_n_test_name = " BM_Complexity_O_N_log_N/manual_time " ;
213
+ const char *big_o_n_lg_n_test_name = " BM_Complexity_O_N_log_N/manual_time_BigO " ;
214
+ const char *rms_o_n_lg_n_test_name = " BM_Complexity_O_N_log_N/manual_time_RMS " ;
188
215
const char *enum_auto_big_o_n_lg_n = " NlgN" ;
189
216
const char *lambda_big_o_n_lg_n = " f\\ (N\\ )" ;
190
217
@@ -193,33 +220,48 @@ ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name,
193
220
rms_o_n_lg_n_test_name, enum_auto_big_o_n_lg_n,
194
221
/* family_index=*/ 6 );
195
222
196
- // Add lambda tests
223
+ // NOTE: auto big-o is wron.g
197
224
ADD_COMPLEXITY_CASES (n_lg_n_test_name, big_o_n_lg_n_test_name,
198
- rms_o_n_lg_n_test_name, lambda_big_o_n_lg_n ,
225
+ rms_o_n_lg_n_test_name, enum_auto_big_o_n_lg_n ,
199
226
/* family_index=*/ 7 );
200
227
228
+ // // Add lambda tests
229
+ ADD_COMPLEXITY_CASES (n_lg_n_test_name, big_o_n_lg_n_test_name,
230
+ rms_o_n_lg_n_test_name, lambda_big_o_n_lg_n,
231
+ /* family_index=*/ 8 );
232
+
201
233
// ========================================================================= //
202
234
// -------- Testing formatting of Complexity with captured args ------------ //
203
235
// ========================================================================= //
204
236
205
237
void BM_ComplexityCaptureArgs (benchmark::State &state, int n) {
206
238
for (auto _ : state) {
207
239
// This test requires a non-zero CPU time to avoid divide-by-zero
208
- auto iterations = state.iterations ();
209
- benchmark::DoNotOptimize (iterations);
240
+ benchmark::DoNotOptimize (state.iterations ());
241
+ double tmp = state.iterations ();
242
+ benchmark::DoNotOptimize (tmp);
243
+ for (benchmark::IterationCount i = 0 ; i < state.iterations (); ++i) {
244
+ benchmark::DoNotOptimize (state.iterations ());
245
+ tmp *= state.iterations ();
246
+ benchmark::DoNotOptimize (tmp);
247
+ }
248
+
249
+ state.SetIterationTime (state.range (0 ) * 42 * 1e-9 );
210
250
}
211
251
state.SetComplexityN (n);
212
252
}
213
253
214
254
BENCHMARK_CAPTURE (BM_ComplexityCaptureArgs, capture_test, 100 )
255
+ ->UseManualTime()
215
256
->Complexity(benchmark::oN)
216
257
->Ranges({{1 , 2 }, {3 , 4 }});
217
258
218
259
const std::string complexity_capture_name =
219
- " BM_ComplexityCaptureArgs/capture_test" ;
260
+ " BM_ComplexityCaptureArgs/capture_test/manual_time " ;
220
261
221
262
ADD_COMPLEXITY_CASES (complexity_capture_name, complexity_capture_name + " _BigO" ,
222
- complexity_capture_name + " _RMS" , " N" , /* family_index=*/ 9 );
263
+ complexity_capture_name + " _RMS" , " N" ,
264
+ /* family_index=*/ 9 );
223
265
224
266
// ========================================================================= //
225
267
// --------------------------- TEST CASES END ------------------------------ //
0 commit comments