xref: /aosp_15_r20/external/cronet/third_party/abseil-cpp/absl/time/duration_benchmark.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 The Abseil Authors.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //      https://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #include <cmath>
15 #include <cstddef>
16 #include <cstdint>
17 #include <ctime>
18 #include <string>
19 
20 #include "absl/base/attributes.h"
21 #include "absl/flags/flag.h"
22 #include "absl/time/time.h"
23 #include "benchmark/benchmark.h"
24 
25 ABSL_FLAG(absl::Duration, absl_duration_flag_for_benchmark,
26           absl::Milliseconds(1),
27           "Flag to use for benchmarking duration flag access speed.");
28 
29 namespace {
30 
31 //
32 // Factory functions
33 //
34 
BM_Duration_Factory_Nanoseconds(benchmark::State & state)35 void BM_Duration_Factory_Nanoseconds(benchmark::State& state) {
36   int64_t i = 0;
37   while (state.KeepRunning()) {
38     benchmark::DoNotOptimize(absl::Nanoseconds(i));
39     i += 314159;
40   }
41 }
42 BENCHMARK(BM_Duration_Factory_Nanoseconds);
43 
BM_Duration_Factory_Microseconds(benchmark::State & state)44 void BM_Duration_Factory_Microseconds(benchmark::State& state) {
45   int64_t i = 0;
46   while (state.KeepRunning()) {
47     benchmark::DoNotOptimize(absl::Microseconds(i));
48     i += 314;
49   }
50 }
51 BENCHMARK(BM_Duration_Factory_Microseconds);
52 
BM_Duration_Factory_Milliseconds(benchmark::State & state)53 void BM_Duration_Factory_Milliseconds(benchmark::State& state) {
54   int64_t i = 0;
55   while (state.KeepRunning()) {
56     benchmark::DoNotOptimize(absl::Milliseconds(i));
57     i += 1;
58   }
59 }
60 BENCHMARK(BM_Duration_Factory_Milliseconds);
61 
BM_Duration_Factory_Seconds(benchmark::State & state)62 void BM_Duration_Factory_Seconds(benchmark::State& state) {
63   int64_t i = 0;
64   while (state.KeepRunning()) {
65     benchmark::DoNotOptimize(absl::Seconds(i));
66     i += 1;
67   }
68 }
69 BENCHMARK(BM_Duration_Factory_Seconds);
70 
BM_Duration_Factory_Minutes(benchmark::State & state)71 void BM_Duration_Factory_Minutes(benchmark::State& state) {
72   int64_t i = 0;
73   while (state.KeepRunning()) {
74     benchmark::DoNotOptimize(absl::Minutes(i));
75     i += 1;
76   }
77 }
78 BENCHMARK(BM_Duration_Factory_Minutes);
79 
BM_Duration_Factory_Hours(benchmark::State & state)80 void BM_Duration_Factory_Hours(benchmark::State& state) {
81   int64_t i = 0;
82   while (state.KeepRunning()) {
83     benchmark::DoNotOptimize(absl::Hours(i));
84     i += 1;
85   }
86 }
87 BENCHMARK(BM_Duration_Factory_Hours);
88 
BM_Duration_Factory_DoubleNanoseconds(benchmark::State & state)89 void BM_Duration_Factory_DoubleNanoseconds(benchmark::State& state) {
90   double d = 1;
91   while (state.KeepRunning()) {
92     benchmark::DoNotOptimize(absl::Nanoseconds(d));
93     d = d * 1.00000001 + 1;
94   }
95 }
96 BENCHMARK(BM_Duration_Factory_DoubleNanoseconds);
97 
BM_Duration_Factory_DoubleMicroseconds(benchmark::State & state)98 void BM_Duration_Factory_DoubleMicroseconds(benchmark::State& state) {
99   double d = 1e-3;
100   while (state.KeepRunning()) {
101     benchmark::DoNotOptimize(absl::Microseconds(d));
102     d = d * 1.00000001 + 1e-3;
103   }
104 }
105 BENCHMARK(BM_Duration_Factory_DoubleMicroseconds);
106 
BM_Duration_Factory_DoubleMilliseconds(benchmark::State & state)107 void BM_Duration_Factory_DoubleMilliseconds(benchmark::State& state) {
108   double d = 1e-6;
109   while (state.KeepRunning()) {
110     benchmark::DoNotOptimize(absl::Milliseconds(d));
111     d = d * 1.00000001 + 1e-6;
112   }
113 }
114 BENCHMARK(BM_Duration_Factory_DoubleMilliseconds);
115 
BM_Duration_Factory_DoubleSeconds(benchmark::State & state)116 void BM_Duration_Factory_DoubleSeconds(benchmark::State& state) {
117   double d = 1e-9;
118   while (state.KeepRunning()) {
119     benchmark::DoNotOptimize(absl::Seconds(d));
120     d = d * 1.00000001 + 1e-9;
121   }
122 }
123 BENCHMARK(BM_Duration_Factory_DoubleSeconds);
124 
BM_Duration_Factory_DoubleMinutes(benchmark::State & state)125 void BM_Duration_Factory_DoubleMinutes(benchmark::State& state) {
126   double d = 1e-9;
127   while (state.KeepRunning()) {
128     benchmark::DoNotOptimize(absl::Minutes(d));
129     d = d * 1.00000001 + 1e-9;
130   }
131 }
132 BENCHMARK(BM_Duration_Factory_DoubleMinutes);
133 
BM_Duration_Factory_DoubleHours(benchmark::State & state)134 void BM_Duration_Factory_DoubleHours(benchmark::State& state) {
135   double d = 1e-9;
136   while (state.KeepRunning()) {
137     benchmark::DoNotOptimize(absl::Hours(d));
138     d = d * 1.00000001 + 1e-9;
139   }
140 }
141 BENCHMARK(BM_Duration_Factory_DoubleHours);
142 
143 //
144 // Arithmetic
145 //
146 
BM_Duration_Addition(benchmark::State & state)147 void BM_Duration_Addition(benchmark::State& state) {
148   absl::Duration d = absl::Nanoseconds(1);
149   absl::Duration step = absl::Milliseconds(1);
150   while (state.KeepRunning()) {
151     benchmark::DoNotOptimize(d += step);
152   }
153 }
154 BENCHMARK(BM_Duration_Addition);
155 
BM_Duration_Subtraction(benchmark::State & state)156 void BM_Duration_Subtraction(benchmark::State& state) {
157   absl::Duration d = absl::Seconds(std::numeric_limits<int64_t>::max());
158   absl::Duration step = absl::Milliseconds(1);
159   while (state.KeepRunning()) {
160     benchmark::DoNotOptimize(d -= step);
161   }
162 }
163 BENCHMARK(BM_Duration_Subtraction);
164 
BM_Duration_Multiplication_Fixed(benchmark::State & state)165 void BM_Duration_Multiplication_Fixed(benchmark::State& state) {
166   absl::Duration d = absl::Milliseconds(1);
167   absl::Duration s;
168   int i = 0;
169   while (state.KeepRunning()) {
170     benchmark::DoNotOptimize(s += d * (i + 1));
171     ++i;
172   }
173 }
174 BENCHMARK(BM_Duration_Multiplication_Fixed);
175 
BM_Duration_Multiplication_Double(benchmark::State & state)176 void BM_Duration_Multiplication_Double(benchmark::State& state) {
177   absl::Duration d = absl::Milliseconds(1);
178   absl::Duration s;
179   int i = 0;
180   while (state.KeepRunning()) {
181     benchmark::DoNotOptimize(s += d * (i + 1.0));
182     ++i;
183   }
184 }
185 BENCHMARK(BM_Duration_Multiplication_Double);
186 
BM_Duration_Division_Fixed(benchmark::State & state)187 void BM_Duration_Division_Fixed(benchmark::State& state) {
188   absl::Duration d = absl::Seconds(1);
189   int i = 0;
190   while (state.KeepRunning()) {
191     benchmark::DoNotOptimize(d /= i + 1);
192     ++i;
193   }
194 }
195 BENCHMARK(BM_Duration_Division_Fixed);
196 
BM_Duration_Division_Double(benchmark::State & state)197 void BM_Duration_Division_Double(benchmark::State& state) {
198   absl::Duration d = absl::Seconds(1);
199   int i = 0;
200   while (state.KeepRunning()) {
201     benchmark::DoNotOptimize(d /= i + 1.0);
202     ++i;
203   }
204 }
205 BENCHMARK(BM_Duration_Division_Double);
206 
BM_Duration_FDivDuration_Nanoseconds(benchmark::State & state)207 void BM_Duration_FDivDuration_Nanoseconds(benchmark::State& state) {
208   double d = 1;
209   int i = 0;
210   while (state.KeepRunning()) {
211     benchmark::DoNotOptimize(
212         d += absl::FDivDuration(absl::Milliseconds(i), absl::Nanoseconds(1)));
213     ++i;
214   }
215 }
216 BENCHMARK(BM_Duration_FDivDuration_Nanoseconds);
217 
BM_Duration_IDivDuration_Nanoseconds(benchmark::State & state)218 void BM_Duration_IDivDuration_Nanoseconds(benchmark::State& state) {
219   int64_t a = 1;
220   absl::Duration ignore;
221   int i = 0;
222   while (state.KeepRunning()) {
223     benchmark::DoNotOptimize(a +=
224                              absl::IDivDuration(absl::Nanoseconds(i),
225                                                 absl::Nanoseconds(1), &ignore));
226     ++i;
227   }
228 }
229 BENCHMARK(BM_Duration_IDivDuration_Nanoseconds);
230 
BM_Duration_IDivDuration_Microseconds(benchmark::State & state)231 void BM_Duration_IDivDuration_Microseconds(benchmark::State& state) {
232   int64_t a = 1;
233   absl::Duration ignore;
234   int i = 0;
235   while (state.KeepRunning()) {
236     benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Microseconds(i),
237                                                      absl::Microseconds(1),
238                                                      &ignore));
239     ++i;
240   }
241 }
242 BENCHMARK(BM_Duration_IDivDuration_Microseconds);
243 
BM_Duration_IDivDuration_Milliseconds(benchmark::State & state)244 void BM_Duration_IDivDuration_Milliseconds(benchmark::State& state) {
245   int64_t a = 1;
246   absl::Duration ignore;
247   int i = 0;
248   while (state.KeepRunning()) {
249     benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Milliseconds(i),
250                                                      absl::Milliseconds(1),
251                                                      &ignore));
252     ++i;
253   }
254 }
255 BENCHMARK(BM_Duration_IDivDuration_Milliseconds);
256 
BM_Duration_IDivDuration_Seconds(benchmark::State & state)257 void BM_Duration_IDivDuration_Seconds(benchmark::State& state) {
258   int64_t a = 1;
259   absl::Duration ignore;
260   int i = 0;
261   while (state.KeepRunning()) {
262     benchmark::DoNotOptimize(
263         a += absl::IDivDuration(absl::Seconds(i), absl::Seconds(1), &ignore));
264     ++i;
265   }
266 }
267 BENCHMARK(BM_Duration_IDivDuration_Seconds);
268 
BM_Duration_IDivDuration_Minutes(benchmark::State & state)269 void BM_Duration_IDivDuration_Minutes(benchmark::State& state) {
270   int64_t a = 1;
271   absl::Duration ignore;
272   int i = 0;
273   while (state.KeepRunning()) {
274     benchmark::DoNotOptimize(
275         a += absl::IDivDuration(absl::Minutes(i), absl::Minutes(1), &ignore));
276     ++i;
277   }
278 }
279 BENCHMARK(BM_Duration_IDivDuration_Minutes);
280 
BM_Duration_IDivDuration_Hours(benchmark::State & state)281 void BM_Duration_IDivDuration_Hours(benchmark::State& state) {
282   int64_t a = 1;
283   absl::Duration ignore;
284   int i = 0;
285   while (state.KeepRunning()) {
286     benchmark::DoNotOptimize(
287         a += absl::IDivDuration(absl::Hours(i), absl::Hours(1), &ignore));
288     ++i;
289   }
290 }
291 BENCHMARK(BM_Duration_IDivDuration_Hours);
292 
BM_Duration_Modulo(benchmark::State & state)293 void BM_Duration_Modulo(benchmark::State& state) {
294   int i = 0;
295   while (state.KeepRunning()) {
296     auto mod = absl::Seconds(i) % absl::Nanoseconds(12345);
297     benchmark::DoNotOptimize(mod);
298     ++i;
299   }
300 }
301 BENCHMARK(BM_Duration_Modulo);
302 
BM_Duration_Modulo_FastPath(benchmark::State & state)303 void BM_Duration_Modulo_FastPath(benchmark::State& state) {
304   int i = 0;
305   while (state.KeepRunning()) {
306     auto mod = absl::Seconds(i) % absl::Milliseconds(1);
307     benchmark::DoNotOptimize(mod);
308     ++i;
309   }
310 }
311 BENCHMARK(BM_Duration_Modulo_FastPath);
312 
BM_Duration_ToInt64Nanoseconds(benchmark::State & state)313 void BM_Duration_ToInt64Nanoseconds(benchmark::State& state) {
314   absl::Duration d = absl::Seconds(100000);
315   while (state.KeepRunning()) {
316     benchmark::DoNotOptimize(absl::ToInt64Nanoseconds(d));
317   }
318 }
319 BENCHMARK(BM_Duration_ToInt64Nanoseconds);
320 
BM_Duration_ToInt64Microseconds(benchmark::State & state)321 void BM_Duration_ToInt64Microseconds(benchmark::State& state) {
322   absl::Duration d = absl::Seconds(100000);
323   while (state.KeepRunning()) {
324     benchmark::DoNotOptimize(absl::ToInt64Microseconds(d));
325   }
326 }
327 BENCHMARK(BM_Duration_ToInt64Microseconds);
328 
BM_Duration_ToInt64Milliseconds(benchmark::State & state)329 void BM_Duration_ToInt64Milliseconds(benchmark::State& state) {
330   absl::Duration d = absl::Seconds(100000);
331   while (state.KeepRunning()) {
332     benchmark::DoNotOptimize(absl::ToInt64Milliseconds(d));
333   }
334 }
335 BENCHMARK(BM_Duration_ToInt64Milliseconds);
336 
BM_Duration_ToInt64Seconds(benchmark::State & state)337 void BM_Duration_ToInt64Seconds(benchmark::State& state) {
338   absl::Duration d = absl::Seconds(100000);
339   while (state.KeepRunning()) {
340     benchmark::DoNotOptimize(absl::ToInt64Seconds(d));
341   }
342 }
343 BENCHMARK(BM_Duration_ToInt64Seconds);
344 
BM_Duration_ToInt64Minutes(benchmark::State & state)345 void BM_Duration_ToInt64Minutes(benchmark::State& state) {
346   absl::Duration d = absl::Seconds(100000);
347   while (state.KeepRunning()) {
348     benchmark::DoNotOptimize(absl::ToInt64Minutes(d));
349   }
350 }
351 BENCHMARK(BM_Duration_ToInt64Minutes);
352 
BM_Duration_ToInt64Hours(benchmark::State & state)353 void BM_Duration_ToInt64Hours(benchmark::State& state) {
354   absl::Duration d = absl::Seconds(100000);
355   while (state.KeepRunning()) {
356     benchmark::DoNotOptimize(absl::ToInt64Hours(d));
357   }
358 }
359 BENCHMARK(BM_Duration_ToInt64Hours);
360 
361 //
362 // To/FromTimespec
363 //
364 
BM_Duration_ToTimespec_AbslTime(benchmark::State & state)365 void BM_Duration_ToTimespec_AbslTime(benchmark::State& state) {
366   absl::Duration d = absl::Seconds(1);
367   while (state.KeepRunning()) {
368     benchmark::DoNotOptimize(absl::ToTimespec(d));
369   }
370 }
371 BENCHMARK(BM_Duration_ToTimespec_AbslTime);
372 
DoubleToTimespec(double seconds)373 ABSL_ATTRIBUTE_NOINLINE timespec DoubleToTimespec(double seconds) {
374   timespec ts;
375   ts.tv_sec = seconds;
376   ts.tv_nsec = (seconds - ts.tv_sec) * (1000 * 1000 * 1000);
377   return ts;
378 }
379 
BM_Duration_ToTimespec_Double(benchmark::State & state)380 void BM_Duration_ToTimespec_Double(benchmark::State& state) {
381   while (state.KeepRunning()) {
382     benchmark::DoNotOptimize(DoubleToTimespec(1.0));
383   }
384 }
385 BENCHMARK(BM_Duration_ToTimespec_Double);
386 
BM_Duration_FromTimespec_AbslTime(benchmark::State & state)387 void BM_Duration_FromTimespec_AbslTime(benchmark::State& state) {
388   timespec ts;
389   ts.tv_sec = 0;
390   ts.tv_nsec = 0;
391   while (state.KeepRunning()) {
392     if (++ts.tv_nsec == 1000 * 1000 * 1000) {
393       ++ts.tv_sec;
394       ts.tv_nsec = 0;
395     }
396     benchmark::DoNotOptimize(absl::DurationFromTimespec(ts));
397   }
398 }
399 BENCHMARK(BM_Duration_FromTimespec_AbslTime);
400 
TimespecToDouble(timespec ts)401 ABSL_ATTRIBUTE_NOINLINE double TimespecToDouble(timespec ts) {
402   return ts.tv_sec + (ts.tv_nsec / (1000 * 1000 * 1000));
403 }
404 
BM_Duration_FromTimespec_Double(benchmark::State & state)405 void BM_Duration_FromTimespec_Double(benchmark::State& state) {
406   timespec ts;
407   ts.tv_sec = 0;
408   ts.tv_nsec = 0;
409   while (state.KeepRunning()) {
410     if (++ts.tv_nsec == 1000 * 1000 * 1000) {
411       ++ts.tv_sec;
412       ts.tv_nsec = 0;
413     }
414     benchmark::DoNotOptimize(TimespecToDouble(ts));
415   }
416 }
417 BENCHMARK(BM_Duration_FromTimespec_Double);
418 
419 //
420 // String conversions
421 //
422 
423 const char* const kDurations[] = {
424     "0",                                   // 0
425     "123ns",                               // 1
426     "1h2m3s",                              // 2
427     "-2h3m4.005006007s",                   // 3
428     "2562047788015215h30m7.99999999975s",  // 4
429 };
430 const int kNumDurations = sizeof(kDurations) / sizeof(kDurations[0]);
431 
BM_Duration_FormatDuration(benchmark::State & state)432 void BM_Duration_FormatDuration(benchmark::State& state) {
433   const std::string s = kDurations[state.range(0)];
434   state.SetLabel(s);
435   absl::Duration d;
436   absl::ParseDuration(kDurations[state.range(0)], &d);
437   while (state.KeepRunning()) {
438     benchmark::DoNotOptimize(absl::FormatDuration(d));
439   }
440 }
441 BENCHMARK(BM_Duration_FormatDuration)->DenseRange(0, kNumDurations - 1);
442 
BM_Duration_ParseDuration(benchmark::State & state)443 void BM_Duration_ParseDuration(benchmark::State& state) {
444   const std::string s = kDurations[state.range(0)];
445   state.SetLabel(s);
446   absl::Duration d;
447   while (state.KeepRunning()) {
448     benchmark::DoNotOptimize(absl::ParseDuration(s, &d));
449   }
450 }
451 BENCHMARK(BM_Duration_ParseDuration)->DenseRange(0, kNumDurations - 1);
452 
453 //
454 // Flag access
455 //
BM_Duration_GetFlag(benchmark::State & state)456 void BM_Duration_GetFlag(benchmark::State& state) {
457   while (state.KeepRunning()) {
458     benchmark::DoNotOptimize(
459         absl::GetFlag(FLAGS_absl_duration_flag_for_benchmark));
460   }
461 }
462 BENCHMARK(BM_Duration_GetFlag);
463 
464 }  // namespace
465