time_benchmark.cc
Go to the documentation of this file.
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 "absl/time/time.h"
15 
16 #if !defined(_WIN32)
17 #include <sys/time.h>
18 #endif // _WIN32
19 #include <algorithm>
20 #include <cmath>
21 #include <cstddef>
22 #include <cstring>
23 #include <ctime>
24 #include <memory>
25 #include <string>
26 
27 #include "absl/time/clock.h"
29 #include "benchmark/benchmark.h"
30 
31 namespace {
32 
33 //
34 // Addition/Subtraction of a duration
35 //
36 
37 void BM_Time_Arithmetic(benchmark::State& state) {
38  const absl::Duration nano = absl::Nanoseconds(1);
39  const absl::Duration sec = absl::Seconds(1);
41  while (state.KeepRunning()) {
42  benchmark::DoNotOptimize(t += nano);
43  benchmark::DoNotOptimize(t -= sec);
44  }
45 }
46 BENCHMARK(BM_Time_Arithmetic);
47 
48 //
49 // Time difference
50 //
51 
52 void BM_Time_Difference(benchmark::State& state) {
53  absl::Time start = absl::Now();
54  absl::Time end = start + absl::Nanoseconds(1);
55  absl::Duration diff;
56  while (state.KeepRunning()) {
57  benchmark::DoNotOptimize(diff += end - start);
58  }
59 }
60 BENCHMARK(BM_Time_Difference);
61 
62 //
63 // ToDateTime
64 //
65 // In each "ToDateTime" benchmark we switch between two instants
66 // separated by at least one transition in order to defeat any
67 // internal caching of previous results (e.g., see local_time_hint_).
68 //
69 // The "UTC" variants use UTC instead of the Google/local time zone.
70 //
71 
72 void BM_Time_ToDateTime_Absl(benchmark::State& state) {
73  const absl::TimeZone tz =
74  absl::time_internal::LoadTimeZone("America/Los_Angeles");
75  absl::Time t = absl::FromUnixSeconds(1384569027);
76  absl::Time t2 = absl::FromUnixSeconds(1418962578);
77  while (state.KeepRunning()) {
78  std::swap(t, t2);
79  t += absl::Seconds(1);
80  benchmark::DoNotOptimize(t.In(tz));
81  }
82 }
83 BENCHMARK(BM_Time_ToDateTime_Absl);
84 
85 void BM_Time_ToDateTime_Libc(benchmark::State& state) {
86  // No timezone support, so just use localtime.
87  time_t t = 1384569027;
88  time_t t2 = 1418962578;
89  while (state.KeepRunning()) {
90  std::swap(t, t2);
91  t += 1;
92  struct tm tm;
93 #if !defined(_WIN32)
94  benchmark::DoNotOptimize(localtime_r(&t, &tm));
95 #else // _WIN32
96  benchmark::DoNotOptimize(localtime_s(&tm, &t));
97 #endif // _WIN32
98  }
99 }
100 BENCHMARK(BM_Time_ToDateTime_Libc);
101 
102 void BM_Time_ToDateTimeUTC_Absl(benchmark::State& state) {
103  const absl::TimeZone tz = absl::UTCTimeZone();
104  absl::Time t = absl::FromUnixSeconds(1384569027);
105  while (state.KeepRunning()) {
106  t += absl::Seconds(1);
107  benchmark::DoNotOptimize(t.In(tz));
108  }
109 }
110 BENCHMARK(BM_Time_ToDateTimeUTC_Absl);
111 
112 void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) {
113  time_t t = 1384569027;
114  while (state.KeepRunning()) {
115  t += 1;
116  struct tm tm;
117 #if !defined(_WIN32)
118  benchmark::DoNotOptimize(gmtime_r(&t, &tm));
119 #else // _WIN32
120  benchmark::DoNotOptimize(gmtime_s(&tm, &t));
121 #endif // _WIN32
122  }
123 }
124 BENCHMARK(BM_Time_ToDateTimeUTC_Libc);
125 
126 //
127 // FromUnixMicros
128 //
129 
130 void BM_Time_FromUnixMicros(benchmark::State& state) {
131  int i = 0;
132  while (state.KeepRunning()) {
133  benchmark::DoNotOptimize(absl::FromUnixMicros(i));
134  ++i;
135  }
136 }
137 BENCHMARK(BM_Time_FromUnixMicros);
138 
139 void BM_Time_ToUnixNanos(benchmark::State& state) {
140  const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
141  while (state.KeepRunning()) {
142  benchmark::DoNotOptimize(ToUnixNanos(t));
143  }
144 }
145 BENCHMARK(BM_Time_ToUnixNanos);
146 
147 void BM_Time_ToUnixMicros(benchmark::State& state) {
148  const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
149  while (state.KeepRunning()) {
150  benchmark::DoNotOptimize(ToUnixMicros(t));
151  }
152 }
153 BENCHMARK(BM_Time_ToUnixMicros);
154 
155 void BM_Time_ToUnixMillis(benchmark::State& state) {
156  const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
157  while (state.KeepRunning()) {
158  benchmark::DoNotOptimize(ToUnixMillis(t));
159  }
160 }
161 BENCHMARK(BM_Time_ToUnixMillis);
162 
163 void BM_Time_ToUnixSeconds(benchmark::State& state) {
164  const absl::Time t = absl::UnixEpoch() + absl::Seconds(123);
165  while (state.KeepRunning()) {
166  benchmark::DoNotOptimize(absl::ToUnixSeconds(t));
167  }
168 }
169 BENCHMARK(BM_Time_ToUnixSeconds);
170 
171 //
172 // FromCivil
173 //
174 // In each "FromCivil" benchmark we switch between two YMDhms values
175 // separated by at least one transition in order to defeat any internal
176 // caching of previous results (e.g., see time_local_hint_).
177 //
178 // The "UTC" variants use UTC instead of the Google/local time zone.
179 // The "Day0" variants require normalization of the day of month.
180 //
181 
182 void BM_Time_FromCivil_Absl(benchmark::State& state) {
183  const absl::TimeZone tz =
184  absl::time_internal::LoadTimeZone("America/Los_Angeles");
185  int i = 0;
186  while (state.KeepRunning()) {
187  if ((i & 1) == 0) {
188  absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz);
189  } else {
190  absl::FromCivil(absl::CivilSecond(2013, 11, 15, 18, 30, 27), tz);
191  }
192  ++i;
193  }
194 }
195 BENCHMARK(BM_Time_FromCivil_Absl);
196 
197 void BM_Time_FromCivil_Libc(benchmark::State& state) {
198  // No timezone support, so just use localtime.
199  int i = 0;
200  while (state.KeepRunning()) {
201  struct tm tm;
202  if ((i & 1) == 0) {
203  tm.tm_year = 2014 - 1900;
204  tm.tm_mon = 12 - 1;
205  tm.tm_mday = 18;
206  tm.tm_hour = 20;
207  tm.tm_min = 16;
208  tm.tm_sec = 18;
209  } else {
210  tm.tm_year = 2013 - 1900;
211  tm.tm_mon = 11 - 1;
212  tm.tm_mday = 15;
213  tm.tm_hour = 18;
214  tm.tm_min = 30;
215  tm.tm_sec = 27;
216  }
217  tm.tm_isdst = -1;
218  mktime(&tm);
219  ++i;
220  }
221 }
222 BENCHMARK(BM_Time_FromCivil_Libc);
223 
224 void BM_Time_FromCivilUTC_Absl(benchmark::State& state) {
225  const absl::TimeZone tz = absl::UTCTimeZone();
226  while (state.KeepRunning()) {
227  absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz);
228  }
229 }
230 BENCHMARK(BM_Time_FromCivilUTC_Absl);
231 
232 void BM_Time_FromCivilDay0_Absl(benchmark::State& state) {
233  const absl::TimeZone tz =
234  absl::time_internal::LoadTimeZone("America/Los_Angeles");
235  int i = 0;
236  while (state.KeepRunning()) {
237  if ((i & 1) == 0) {
238  absl::FromCivil(absl::CivilSecond(2014, 12, 0, 20, 16, 18), tz);
239  } else {
240  absl::FromCivil(absl::CivilSecond(2013, 11, 0, 18, 30, 27), tz);
241  }
242  ++i;
243  }
244 }
245 BENCHMARK(BM_Time_FromCivilDay0_Absl);
246 
247 void BM_Time_FromCivilDay0_Libc(benchmark::State& state) {
248  // No timezone support, so just use localtime.
249  int i = 0;
250  while (state.KeepRunning()) {
251  struct tm tm;
252  if ((i & 1) == 0) {
253  tm.tm_year = 2014 - 1900;
254  tm.tm_mon = 12 - 1;
255  tm.tm_mday = 0;
256  tm.tm_hour = 20;
257  tm.tm_min = 16;
258  tm.tm_sec = 18;
259  } else {
260  tm.tm_year = 2013 - 1900;
261  tm.tm_mon = 11 - 1;
262  tm.tm_mday = 0;
263  tm.tm_hour = 18;
264  tm.tm_min = 30;
265  tm.tm_sec = 27;
266  }
267  tm.tm_isdst = -1;
268  mktime(&tm);
269  ++i;
270  }
271 }
272 BENCHMARK(BM_Time_FromCivilDay0_Libc);
273 
274 //
275 // To/FromTimespec
276 //
277 
278 void BM_Time_ToTimespec(benchmark::State& state) {
279  absl::Time now = absl::Now();
280  while (state.KeepRunning()) {
281  benchmark::DoNotOptimize(absl::ToTimespec(now));
282  }
283 }
284 BENCHMARK(BM_Time_ToTimespec);
285 
286 void BM_Time_FromTimespec(benchmark::State& state) {
287  timespec ts = absl::ToTimespec(absl::Now());
288  while (state.KeepRunning()) {
289  if (++ts.tv_nsec == 1000 * 1000 * 1000) {
290  ++ts.tv_sec;
291  ts.tv_nsec = 0;
292  }
293  benchmark::DoNotOptimize(absl::TimeFromTimespec(ts));
294  }
295 }
296 BENCHMARK(BM_Time_FromTimespec);
297 
298 //
299 // Comparison with InfiniteFuture/Past
300 //
301 
302 void BM_Time_InfiniteFuture(benchmark::State& state) {
303  while (state.KeepRunning()) {
304  benchmark::DoNotOptimize(absl::InfiniteFuture());
305  }
306 }
307 BENCHMARK(BM_Time_InfiniteFuture);
308 
309 void BM_Time_InfinitePast(benchmark::State& state) {
310  while (state.KeepRunning()) {
311  benchmark::DoNotOptimize(absl::InfinitePast());
312  }
313 }
314 BENCHMARK(BM_Time_InfinitePast);
315 
316 } // namespace
timespec ToTimespec(Duration d)
Definition: duration.cc:598
constexpr Time InfiniteFuture()
Definition: time.h:701
Time Now()
Definition: clock.cc:37
int64_t ToUnixMillis(Time t)
Definition: time.cc:257
TimeZone UTCTimeZone()
Definition: time.h:1026
char * end
int64_t ToUnixMicros(Time t)
Definition: time.cc:247
cctz::time_point< cctz::seconds > sec
Definition: format.cc:38
constexpr Time FromUnixSeconds(int64_t s)
Definition: time.h:1549
constexpr Time UnixEpoch()
Definition: time.h:686
constexpr Time FromUnixMicros(int64_t us)
Definition: time.h:1541
absl::Time TimeFromTimespec(timespec ts)
Definition: time.cc:282
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
int64_t ToUnixSeconds(Time t)
Definition: time.cc:267
constexpr Duration Seconds(int64_t n)
Definition: time.h:1461
Time FromCivil(CivilSecond ct, TimeZone tz)
Definition: time.h:1085
TimeZone LoadTimeZone(const std::string &name)
Definition: test_util.cc:29
constexpr Duration Nanoseconds(int64_t n)
Definition: time.h:1452
Breakdown In(TimeZone tz) const
Definition: time.cc:200
int64_t ToUnixNanos(Time t)
Definition: time.cc:237
constexpr Time InfinitePast()
Definition: time.h:709


abseil_cpp
Author(s):
autogenerated on Tue Jun 18 2019 19:44:37