• 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/time/time.h"
22 #include "benchmark/benchmark.h"
23 
24 namespace {
25 
26 //
27 // Factory functions
28 //
29 
BM_Duration_Factory_Nanoseconds(benchmark::State & state)30 void BM_Duration_Factory_Nanoseconds(benchmark::State& state) {
31   int64_t i = 0;
32   while (state.KeepRunning()) {
33     benchmark::DoNotOptimize(absl::Nanoseconds(i));
34     i += 314159;
35   }
36 }
37 BENCHMARK(BM_Duration_Factory_Nanoseconds);
38 
BM_Duration_Factory_Microseconds(benchmark::State & state)39 void BM_Duration_Factory_Microseconds(benchmark::State& state) {
40   int64_t i = 0;
41   while (state.KeepRunning()) {
42     benchmark::DoNotOptimize(absl::Microseconds(i));
43     i += 314;
44   }
45 }
46 BENCHMARK(BM_Duration_Factory_Microseconds);
47 
BM_Duration_Factory_Milliseconds(benchmark::State & state)48 void BM_Duration_Factory_Milliseconds(benchmark::State& state) {
49   int64_t i = 0;
50   while (state.KeepRunning()) {
51     benchmark::DoNotOptimize(absl::Milliseconds(i));
52     i += 1;
53   }
54 }
55 BENCHMARK(BM_Duration_Factory_Milliseconds);
56 
BM_Duration_Factory_Seconds(benchmark::State & state)57 void BM_Duration_Factory_Seconds(benchmark::State& state) {
58   int64_t i = 0;
59   while (state.KeepRunning()) {
60     benchmark::DoNotOptimize(absl::Seconds(i));
61     i += 1;
62   }
63 }
64 BENCHMARK(BM_Duration_Factory_Seconds);
65 
BM_Duration_Factory_Minutes(benchmark::State & state)66 void BM_Duration_Factory_Minutes(benchmark::State& state) {
67   int64_t i = 0;
68   while (state.KeepRunning()) {
69     benchmark::DoNotOptimize(absl::Minutes(i));
70     i += 1;
71   }
72 }
73 BENCHMARK(BM_Duration_Factory_Minutes);
74 
BM_Duration_Factory_Hours(benchmark::State & state)75 void BM_Duration_Factory_Hours(benchmark::State& state) {
76   int64_t i = 0;
77   while (state.KeepRunning()) {
78     benchmark::DoNotOptimize(absl::Hours(i));
79     i += 1;
80   }
81 }
82 BENCHMARK(BM_Duration_Factory_Hours);
83 
BM_Duration_Factory_DoubleNanoseconds(benchmark::State & state)84 void BM_Duration_Factory_DoubleNanoseconds(benchmark::State& state) {
85   double d = 1;
86   while (state.KeepRunning()) {
87     benchmark::DoNotOptimize(absl::Nanoseconds(d));
88     d = d * 1.00000001 + 1;
89   }
90 }
91 BENCHMARK(BM_Duration_Factory_DoubleNanoseconds);
92 
BM_Duration_Factory_DoubleMicroseconds(benchmark::State & state)93 void BM_Duration_Factory_DoubleMicroseconds(benchmark::State& state) {
94   double d = 1e-3;
95   while (state.KeepRunning()) {
96     benchmark::DoNotOptimize(absl::Microseconds(d));
97     d = d * 1.00000001 + 1e-3;
98   }
99 }
100 BENCHMARK(BM_Duration_Factory_DoubleMicroseconds);
101 
BM_Duration_Factory_DoubleMilliseconds(benchmark::State & state)102 void BM_Duration_Factory_DoubleMilliseconds(benchmark::State& state) {
103   double d = 1e-6;
104   while (state.KeepRunning()) {
105     benchmark::DoNotOptimize(absl::Milliseconds(d));
106     d = d * 1.00000001 + 1e-6;
107   }
108 }
109 BENCHMARK(BM_Duration_Factory_DoubleMilliseconds);
110 
BM_Duration_Factory_DoubleSeconds(benchmark::State & state)111 void BM_Duration_Factory_DoubleSeconds(benchmark::State& state) {
112   double d = 1e-9;
113   while (state.KeepRunning()) {
114     benchmark::DoNotOptimize(absl::Seconds(d));
115     d = d * 1.00000001 + 1e-9;
116   }
117 }
118 BENCHMARK(BM_Duration_Factory_DoubleSeconds);
119 
BM_Duration_Factory_DoubleMinutes(benchmark::State & state)120 void BM_Duration_Factory_DoubleMinutes(benchmark::State& state) {
121   double d = 1e-9;
122   while (state.KeepRunning()) {
123     benchmark::DoNotOptimize(absl::Minutes(d));
124     d = d * 1.00000001 + 1e-9;
125   }
126 }
127 BENCHMARK(BM_Duration_Factory_DoubleMinutes);
128 
BM_Duration_Factory_DoubleHours(benchmark::State & state)129 void BM_Duration_Factory_DoubleHours(benchmark::State& state) {
130   double d = 1e-9;
131   while (state.KeepRunning()) {
132     benchmark::DoNotOptimize(absl::Hours(d));
133     d = d * 1.00000001 + 1e-9;
134   }
135 }
136 BENCHMARK(BM_Duration_Factory_DoubleHours);
137 
138 //
139 // Arithmetic
140 //
141 
BM_Duration_Addition(benchmark::State & state)142 void BM_Duration_Addition(benchmark::State& state) {
143   absl::Duration d = absl::Nanoseconds(1);
144   absl::Duration step = absl::Milliseconds(1);
145   while (state.KeepRunning()) {
146     benchmark::DoNotOptimize(d += step);
147   }
148 }
149 BENCHMARK(BM_Duration_Addition);
150 
BM_Duration_Subtraction(benchmark::State & state)151 void BM_Duration_Subtraction(benchmark::State& state) {
152   absl::Duration d = absl::Seconds(std::numeric_limits<int64_t>::max());
153   absl::Duration step = absl::Milliseconds(1);
154   while (state.KeepRunning()) {
155     benchmark::DoNotOptimize(d -= step);
156   }
157 }
158 BENCHMARK(BM_Duration_Subtraction);
159 
BM_Duration_Multiplication_Fixed(benchmark::State & state)160 void BM_Duration_Multiplication_Fixed(benchmark::State& state) {
161   absl::Duration d = absl::Milliseconds(1);
162   absl::Duration s;
163   int i = 0;
164   while (state.KeepRunning()) {
165     benchmark::DoNotOptimize(s += d * (i + 1));
166     ++i;
167   }
168 }
169 BENCHMARK(BM_Duration_Multiplication_Fixed);
170 
BM_Duration_Multiplication_Double(benchmark::State & state)171 void BM_Duration_Multiplication_Double(benchmark::State& state) {
172   absl::Duration d = absl::Milliseconds(1);
173   absl::Duration s;
174   int i = 0;
175   while (state.KeepRunning()) {
176     benchmark::DoNotOptimize(s += d * (i + 1.0));
177     ++i;
178   }
179 }
180 BENCHMARK(BM_Duration_Multiplication_Double);
181 
BM_Duration_Division_Fixed(benchmark::State & state)182 void BM_Duration_Division_Fixed(benchmark::State& state) {
183   absl::Duration d = absl::Seconds(1);
184   int i = 0;
185   while (state.KeepRunning()) {
186     benchmark::DoNotOptimize(d /= i + 1);
187     ++i;
188   }
189 }
190 BENCHMARK(BM_Duration_Division_Fixed);
191 
BM_Duration_Division_Double(benchmark::State & state)192 void BM_Duration_Division_Double(benchmark::State& state) {
193   absl::Duration d = absl::Seconds(1);
194   int i = 0;
195   while (state.KeepRunning()) {
196     benchmark::DoNotOptimize(d /= i + 1.0);
197     ++i;
198   }
199 }
200 BENCHMARK(BM_Duration_Division_Double);
201 
BM_Duration_FDivDuration_Nanoseconds(benchmark::State & state)202 void BM_Duration_FDivDuration_Nanoseconds(benchmark::State& state) {
203   double d = 1;
204   int i = 0;
205   while (state.KeepRunning()) {
206     benchmark::DoNotOptimize(
207         d += absl::FDivDuration(absl::Milliseconds(i), absl::Nanoseconds(1)));
208     ++i;
209   }
210 }
211 BENCHMARK(BM_Duration_FDivDuration_Nanoseconds);
212 
BM_Duration_IDivDuration_Nanoseconds(benchmark::State & state)213 void BM_Duration_IDivDuration_Nanoseconds(benchmark::State& state) {
214   int64_t a = 1;
215   absl::Duration ignore;
216   int i = 0;
217   while (state.KeepRunning()) {
218     benchmark::DoNotOptimize(a +=
219                              absl::IDivDuration(absl::Nanoseconds(i),
220                                                 absl::Nanoseconds(1), &ignore));
221     ++i;
222   }
223 }
224 BENCHMARK(BM_Duration_IDivDuration_Nanoseconds);
225 
BM_Duration_IDivDuration_Microseconds(benchmark::State & state)226 void BM_Duration_IDivDuration_Microseconds(benchmark::State& state) {
227   int64_t a = 1;
228   absl::Duration ignore;
229   int i = 0;
230   while (state.KeepRunning()) {
231     benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Microseconds(i),
232                                                      absl::Microseconds(1),
233                                                      &ignore));
234     ++i;
235   }
236 }
237 BENCHMARK(BM_Duration_IDivDuration_Microseconds);
238 
BM_Duration_IDivDuration_Milliseconds(benchmark::State & state)239 void BM_Duration_IDivDuration_Milliseconds(benchmark::State& state) {
240   int64_t a = 1;
241   absl::Duration ignore;
242   int i = 0;
243   while (state.KeepRunning()) {
244     benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Milliseconds(i),
245                                                      absl::Milliseconds(1),
246                                                      &ignore));
247     ++i;
248   }
249 }
250 BENCHMARK(BM_Duration_IDivDuration_Milliseconds);
251 
BM_Duration_IDivDuration_Seconds(benchmark::State & state)252 void BM_Duration_IDivDuration_Seconds(benchmark::State& state) {
253   int64_t a = 1;
254   absl::Duration ignore;
255   int i = 0;
256   while (state.KeepRunning()) {
257     benchmark::DoNotOptimize(
258         a += absl::IDivDuration(absl::Seconds(i), absl::Seconds(1), &ignore));
259     ++i;
260   }
261 }
262 BENCHMARK(BM_Duration_IDivDuration_Seconds);
263 
BM_Duration_IDivDuration_Minutes(benchmark::State & state)264 void BM_Duration_IDivDuration_Minutes(benchmark::State& state) {
265   int64_t a = 1;
266   absl::Duration ignore;
267   int i = 0;
268   while (state.KeepRunning()) {
269     benchmark::DoNotOptimize(
270         a += absl::IDivDuration(absl::Minutes(i), absl::Minutes(1), &ignore));
271     ++i;
272   }
273 }
274 BENCHMARK(BM_Duration_IDivDuration_Minutes);
275 
BM_Duration_IDivDuration_Hours(benchmark::State & state)276 void BM_Duration_IDivDuration_Hours(benchmark::State& state) {
277   int64_t a = 1;
278   absl::Duration ignore;
279   int i = 0;
280   while (state.KeepRunning()) {
281     benchmark::DoNotOptimize(
282         a += absl::IDivDuration(absl::Hours(i), absl::Hours(1), &ignore));
283     ++i;
284   }
285 }
286 BENCHMARK(BM_Duration_IDivDuration_Hours);
287 
BM_Duration_ToInt64Nanoseconds(benchmark::State & state)288 void BM_Duration_ToInt64Nanoseconds(benchmark::State& state) {
289   absl::Duration d = absl::Seconds(100000);
290   while (state.KeepRunning()) {
291     benchmark::DoNotOptimize(absl::ToInt64Nanoseconds(d));
292   }
293 }
294 BENCHMARK(BM_Duration_ToInt64Nanoseconds);
295 
BM_Duration_ToInt64Microseconds(benchmark::State & state)296 void BM_Duration_ToInt64Microseconds(benchmark::State& state) {
297   absl::Duration d = absl::Seconds(100000);
298   while (state.KeepRunning()) {
299     benchmark::DoNotOptimize(absl::ToInt64Microseconds(d));
300   }
301 }
302 BENCHMARK(BM_Duration_ToInt64Microseconds);
303 
BM_Duration_ToInt64Milliseconds(benchmark::State & state)304 void BM_Duration_ToInt64Milliseconds(benchmark::State& state) {
305   absl::Duration d = absl::Seconds(100000);
306   while (state.KeepRunning()) {
307     benchmark::DoNotOptimize(absl::ToInt64Milliseconds(d));
308   }
309 }
310 BENCHMARK(BM_Duration_ToInt64Milliseconds);
311 
BM_Duration_ToInt64Seconds(benchmark::State & state)312 void BM_Duration_ToInt64Seconds(benchmark::State& state) {
313   absl::Duration d = absl::Seconds(100000);
314   while (state.KeepRunning()) {
315     benchmark::DoNotOptimize(absl::ToInt64Seconds(d));
316   }
317 }
318 BENCHMARK(BM_Duration_ToInt64Seconds);
319 
BM_Duration_ToInt64Minutes(benchmark::State & state)320 void BM_Duration_ToInt64Minutes(benchmark::State& state) {
321   absl::Duration d = absl::Seconds(100000);
322   while (state.KeepRunning()) {
323     benchmark::DoNotOptimize(absl::ToInt64Minutes(d));
324   }
325 }
326 BENCHMARK(BM_Duration_ToInt64Minutes);
327 
BM_Duration_ToInt64Hours(benchmark::State & state)328 void BM_Duration_ToInt64Hours(benchmark::State& state) {
329   absl::Duration d = absl::Seconds(100000);
330   while (state.KeepRunning()) {
331     benchmark::DoNotOptimize(absl::ToInt64Hours(d));
332   }
333 }
334 BENCHMARK(BM_Duration_ToInt64Hours);
335 
336 //
337 // To/FromTimespec
338 //
339 
BM_Duration_ToTimespec_AbslTime(benchmark::State & state)340 void BM_Duration_ToTimespec_AbslTime(benchmark::State& state) {
341   absl::Duration d = absl::Seconds(1);
342   while (state.KeepRunning()) {
343     benchmark::DoNotOptimize(absl::ToTimespec(d));
344   }
345 }
346 BENCHMARK(BM_Duration_ToTimespec_AbslTime);
347 
DoubleToTimespec(double seconds)348 ABSL_ATTRIBUTE_NOINLINE timespec DoubleToTimespec(double seconds) {
349   timespec ts;
350   ts.tv_sec = seconds;
351   ts.tv_nsec = (seconds - ts.tv_sec) * (1000 * 1000 * 1000);
352   return ts;
353 }
354 
BM_Duration_ToTimespec_Double(benchmark::State & state)355 void BM_Duration_ToTimespec_Double(benchmark::State& state) {
356   while (state.KeepRunning()) {
357     benchmark::DoNotOptimize(DoubleToTimespec(1.0));
358   }
359 }
360 BENCHMARK(BM_Duration_ToTimespec_Double);
361 
BM_Duration_FromTimespec_AbslTime(benchmark::State & state)362 void BM_Duration_FromTimespec_AbslTime(benchmark::State& state) {
363   timespec ts;
364   ts.tv_sec = 0;
365   ts.tv_nsec = 0;
366   while (state.KeepRunning()) {
367     if (++ts.tv_nsec == 1000 * 1000 * 1000) {
368       ++ts.tv_sec;
369       ts.tv_nsec = 0;
370     }
371     benchmark::DoNotOptimize(absl::DurationFromTimespec(ts));
372   }
373 }
374 BENCHMARK(BM_Duration_FromTimespec_AbslTime);
375 
TimespecToDouble(timespec ts)376 ABSL_ATTRIBUTE_NOINLINE double TimespecToDouble(timespec ts) {
377   return ts.tv_sec + (ts.tv_nsec / (1000 * 1000 * 1000));
378 }
379 
BM_Duration_FromTimespec_Double(benchmark::State & state)380 void BM_Duration_FromTimespec_Double(benchmark::State& state) {
381   timespec ts;
382   ts.tv_sec = 0;
383   ts.tv_nsec = 0;
384   while (state.KeepRunning()) {
385     if (++ts.tv_nsec == 1000 * 1000 * 1000) {
386       ++ts.tv_sec;
387       ts.tv_nsec = 0;
388     }
389     benchmark::DoNotOptimize(TimespecToDouble(ts));
390   }
391 }
392 BENCHMARK(BM_Duration_FromTimespec_Double);
393 
394 //
395 // String conversions
396 //
397 
398 const char* const kDurations[] = {
399     "0",                                   // 0
400     "123ns",                               // 1
401     "1h2m3s",                              // 2
402     "-2h3m4.005006007s",                   // 3
403     "2562047788015215h30m7.99999999975s",  // 4
404 };
405 const int kNumDurations = sizeof(kDurations) / sizeof(kDurations[0]);
406 
BM_Duration_FormatDuration(benchmark::State & state)407 void BM_Duration_FormatDuration(benchmark::State& state) {
408   const std::string s = kDurations[state.range(0)];
409   state.SetLabel(s);
410   absl::Duration d;
411   absl::ParseDuration(kDurations[state.range(0)], &d);
412   while (state.KeepRunning()) {
413     benchmark::DoNotOptimize(absl::FormatDuration(d));
414   }
415 }
416 BENCHMARK(BM_Duration_FormatDuration)->DenseRange(0, kNumDurations - 1);
417 
BM_Duration_ParseDuration(benchmark::State & state)418 void BM_Duration_ParseDuration(benchmark::State& state) {
419   const std::string s = kDurations[state.range(0)];
420   state.SetLabel(s);
421   absl::Duration d;
422   while (state.KeepRunning()) {
423     benchmark::DoNotOptimize(absl::ParseDuration(s, &d));
424   }
425 }
426 BENCHMARK(BM_Duration_ParseDuration)->DenseRange(0, kNumDurations - 1);
427 
428 }  // namespace
429