tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

time_benchmark.cc (8445B)


      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"
     28 #include "absl/time/internal/test_util.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);
     40  absl::Time t = absl::UnixEpoch();
     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      benchmark::DoNotOptimize(
    189          absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz));
    190    } else {
    191      benchmark::DoNotOptimize(
    192          absl::FromCivil(absl::CivilSecond(2013, 11, 15, 18, 30, 27), tz));
    193    }
    194    ++i;
    195  }
    196 }
    197 BENCHMARK(BM_Time_FromCivil_Absl);
    198 
    199 void BM_Time_FromCivil_Libc(benchmark::State& state) {
    200  // No timezone support, so just use localtime.
    201  int i = 0;
    202  while (state.KeepRunning()) {
    203    struct tm tm;
    204    if ((i & 1) == 0) {
    205      tm.tm_year = 2014 - 1900;
    206      tm.tm_mon = 12 - 1;
    207      tm.tm_mday = 18;
    208      tm.tm_hour = 20;
    209      tm.tm_min = 16;
    210      tm.tm_sec = 18;
    211    } else {
    212      tm.tm_year = 2013 - 1900;
    213      tm.tm_mon = 11 - 1;
    214      tm.tm_mday = 15;
    215      tm.tm_hour = 18;
    216      tm.tm_min = 30;
    217      tm.tm_sec = 27;
    218    }
    219    tm.tm_isdst = -1;
    220    mktime(&tm);
    221    ++i;
    222  }
    223 }
    224 BENCHMARK(BM_Time_FromCivil_Libc);
    225 
    226 void BM_Time_FromCivilUTC_Absl(benchmark::State& state) {
    227  const absl::TimeZone tz = absl::UTCTimeZone();
    228  while (state.KeepRunning()) {
    229    benchmark::DoNotOptimize(
    230        absl::FromCivil(absl::CivilSecond(2014, 12, 18, 20, 16, 18), tz));
    231  }
    232 }
    233 BENCHMARK(BM_Time_FromCivilUTC_Absl);
    234 
    235 void BM_Time_FromCivilDay0_Absl(benchmark::State& state) {
    236  const absl::TimeZone tz =
    237      absl::time_internal::LoadTimeZone("America/Los_Angeles");
    238  int i = 0;
    239  while (state.KeepRunning()) {
    240    if ((i & 1) == 0) {
    241      benchmark::DoNotOptimize(
    242          absl::FromCivil(absl::CivilSecond(2014, 12, 0, 20, 16, 18), tz));
    243    } else {
    244      benchmark::DoNotOptimize(
    245          absl::FromCivil(absl::CivilSecond(2013, 11, 0, 18, 30, 27), tz));
    246    }
    247    ++i;
    248  }
    249 }
    250 BENCHMARK(BM_Time_FromCivilDay0_Absl);
    251 
    252 void BM_Time_FromCivilDay0_Libc(benchmark::State& state) {
    253  // No timezone support, so just use localtime.
    254  int i = 0;
    255  while (state.KeepRunning()) {
    256    struct tm tm;
    257    if ((i & 1) == 0) {
    258      tm.tm_year = 2014 - 1900;
    259      tm.tm_mon = 12 - 1;
    260      tm.tm_mday = 0;
    261      tm.tm_hour = 20;
    262      tm.tm_min = 16;
    263      tm.tm_sec = 18;
    264    } else {
    265      tm.tm_year = 2013 - 1900;
    266      tm.tm_mon = 11 - 1;
    267      tm.tm_mday = 0;
    268      tm.tm_hour = 18;
    269      tm.tm_min = 30;
    270      tm.tm_sec = 27;
    271    }
    272    tm.tm_isdst = -1;
    273    mktime(&tm);
    274    ++i;
    275  }
    276 }
    277 BENCHMARK(BM_Time_FromCivilDay0_Libc);
    278 
    279 //
    280 // To/FromTimespec
    281 //
    282 
    283 void BM_Time_ToTimespec(benchmark::State& state) {
    284  absl::Time now = absl::Now();
    285  while (state.KeepRunning()) {
    286    benchmark::DoNotOptimize(absl::ToTimespec(now));
    287  }
    288 }
    289 BENCHMARK(BM_Time_ToTimespec);
    290 
    291 void BM_Time_FromTimespec(benchmark::State& state) {
    292  timespec ts = absl::ToTimespec(absl::Now());
    293  while (state.KeepRunning()) {
    294    if (++ts.tv_nsec == 1000 * 1000 * 1000) {
    295      ++ts.tv_sec;
    296      ts.tv_nsec = 0;
    297    }
    298    benchmark::DoNotOptimize(absl::TimeFromTimespec(ts));
    299  }
    300 }
    301 BENCHMARK(BM_Time_FromTimespec);
    302 
    303 //
    304 // Comparison with InfiniteFuture/Past
    305 //
    306 
    307 void BM_Time_InfiniteFuture(benchmark::State& state) {
    308  while (state.KeepRunning()) {
    309    benchmark::DoNotOptimize(absl::InfiniteFuture());
    310  }
    311 }
    312 BENCHMARK(BM_Time_InfiniteFuture);
    313 
    314 void BM_Time_InfinitePast(benchmark::State& state) {
    315  while (state.KeepRunning()) {
    316    benchmark::DoNotOptimize(absl::InfinitePast());
    317  }
    318 }
    319 BENCHMARK(BM_Time_InfinitePast);
    320 
    321 }  // namespace