• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ToInt64Nanoseconds(benchmark::State & state)293 void BM_Duration_ToInt64Nanoseconds(benchmark::State& state) {
294   absl::Duration d = absl::Seconds(100000);
295   while (state.KeepRunning()) {
296     benchmark::DoNotOptimize(absl::ToInt64Nanoseconds(d));
297   }
298 }
299 BENCHMARK(BM_Duration_ToInt64Nanoseconds);
300 
BM_Duration_ToInt64Microseconds(benchmark::State & state)301 void BM_Duration_ToInt64Microseconds(benchmark::State& state) {
302   absl::Duration d = absl::Seconds(100000);
303   while (state.KeepRunning()) {
304     benchmark::DoNotOptimize(absl::ToInt64Microseconds(d));
305   }
306 }
307 BENCHMARK(BM_Duration_ToInt64Microseconds);
308 
BM_Duration_ToInt64Milliseconds(benchmark::State & state)309 void BM_Duration_ToInt64Milliseconds(benchmark::State& state) {
310   absl::Duration d = absl::Seconds(100000);
311   while (state.KeepRunning()) {
312     benchmark::DoNotOptimize(absl::ToInt64Milliseconds(d));
313   }
314 }
315 BENCHMARK(BM_Duration_ToInt64Milliseconds);
316 
BM_Duration_ToInt64Seconds(benchmark::State & state)317 void BM_Duration_ToInt64Seconds(benchmark::State& state) {
318   absl::Duration d = absl::Seconds(100000);
319   while (state.KeepRunning()) {
320     benchmark::DoNotOptimize(absl::ToInt64Seconds(d));
321   }
322 }
323 BENCHMARK(BM_Duration_ToInt64Seconds);
324 
BM_Duration_ToInt64Minutes(benchmark::State & state)325 void BM_Duration_ToInt64Minutes(benchmark::State& state) {
326   absl::Duration d = absl::Seconds(100000);
327   while (state.KeepRunning()) {
328     benchmark::DoNotOptimize(absl::ToInt64Minutes(d));
329   }
330 }
331 BENCHMARK(BM_Duration_ToInt64Minutes);
332 
BM_Duration_ToInt64Hours(benchmark::State & state)333 void BM_Duration_ToInt64Hours(benchmark::State& state) {
334   absl::Duration d = absl::Seconds(100000);
335   while (state.KeepRunning()) {
336     benchmark::DoNotOptimize(absl::ToInt64Hours(d));
337   }
338 }
339 BENCHMARK(BM_Duration_ToInt64Hours);
340 
341 //
342 // To/FromTimespec
343 //
344 
BM_Duration_ToTimespec_AbslTime(benchmark::State & state)345 void BM_Duration_ToTimespec_AbslTime(benchmark::State& state) {
346   absl::Duration d = absl::Seconds(1);
347   while (state.KeepRunning()) {
348     benchmark::DoNotOptimize(absl::ToTimespec(d));
349   }
350 }
351 BENCHMARK(BM_Duration_ToTimespec_AbslTime);
352 
DoubleToTimespec(double seconds)353 ABSL_ATTRIBUTE_NOINLINE timespec DoubleToTimespec(double seconds) {
354   timespec ts;
355   ts.tv_sec = seconds;
356   ts.tv_nsec = (seconds - ts.tv_sec) * (1000 * 1000 * 1000);
357   return ts;
358 }
359 
BM_Duration_ToTimespec_Double(benchmark::State & state)360 void BM_Duration_ToTimespec_Double(benchmark::State& state) {
361   while (state.KeepRunning()) {
362     benchmark::DoNotOptimize(DoubleToTimespec(1.0));
363   }
364 }
365 BENCHMARK(BM_Duration_ToTimespec_Double);
366 
BM_Duration_FromTimespec_AbslTime(benchmark::State & state)367 void BM_Duration_FromTimespec_AbslTime(benchmark::State& state) {
368   timespec ts;
369   ts.tv_sec = 0;
370   ts.tv_nsec = 0;
371   while (state.KeepRunning()) {
372     if (++ts.tv_nsec == 1000 * 1000 * 1000) {
373       ++ts.tv_sec;
374       ts.tv_nsec = 0;
375     }
376     benchmark::DoNotOptimize(absl::DurationFromTimespec(ts));
377   }
378 }
379 BENCHMARK(BM_Duration_FromTimespec_AbslTime);
380 
TimespecToDouble(timespec ts)381 ABSL_ATTRIBUTE_NOINLINE double TimespecToDouble(timespec ts) {
382   return ts.tv_sec + (ts.tv_nsec / (1000 * 1000 * 1000));
383 }
384 
BM_Duration_FromTimespec_Double(benchmark::State & state)385 void BM_Duration_FromTimespec_Double(benchmark::State& state) {
386   timespec ts;
387   ts.tv_sec = 0;
388   ts.tv_nsec = 0;
389   while (state.KeepRunning()) {
390     if (++ts.tv_nsec == 1000 * 1000 * 1000) {
391       ++ts.tv_sec;
392       ts.tv_nsec = 0;
393     }
394     benchmark::DoNotOptimize(TimespecToDouble(ts));
395   }
396 }
397 BENCHMARK(BM_Duration_FromTimespec_Double);
398 
399 //
400 // String conversions
401 //
402 
403 const char* const kDurations[] = {
404     "0",                                   // 0
405     "123ns",                               // 1
406     "1h2m3s",                              // 2
407     "-2h3m4.005006007s",                   // 3
408     "2562047788015215h30m7.99999999975s",  // 4
409 };
410 const int kNumDurations = sizeof(kDurations) / sizeof(kDurations[0]);
411 
BM_Duration_FormatDuration(benchmark::State & state)412 void BM_Duration_FormatDuration(benchmark::State& state) {
413   const std::string s = kDurations[state.range(0)];
414   state.SetLabel(s);
415   absl::Duration d;
416   absl::ParseDuration(kDurations[state.range(0)], &d);
417   while (state.KeepRunning()) {
418     benchmark::DoNotOptimize(absl::FormatDuration(d));
419   }
420 }
421 BENCHMARK(BM_Duration_FormatDuration)->DenseRange(0, kNumDurations - 1);
422 
BM_Duration_ParseDuration(benchmark::State & state)423 void BM_Duration_ParseDuration(benchmark::State& state) {
424   const std::string s = kDurations[state.range(0)];
425   state.SetLabel(s);
426   absl::Duration d;
427   while (state.KeepRunning()) {
428     benchmark::DoNotOptimize(absl::ParseDuration(s, &d));
429   }
430 }
431 BENCHMARK(BM_Duration_ParseDuration)->DenseRange(0, kNumDurations - 1);
432 
433 //
434 // Flag access
435 //
BM_Duration_GetFlag(benchmark::State & state)436 void BM_Duration_GetFlag(benchmark::State& state) {
437   while (state.KeepRunning()) {
438     benchmark::DoNotOptimize(
439         absl::GetFlag(FLAGS_absl_duration_flag_for_benchmark));
440   }
441 }
442 BENCHMARK(BM_Duration_GetFlag);
443 
444 }  // namespace
445