tor-browser

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

duration_benchmark.cc (12783B)


      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 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    401 ABSL_ATTRIBUTE_NOINLINE double TimespecToDouble(timespec ts) {
    402  return ts.tv_sec + (ts.tv_nsec / (1000 * 1000 * 1000));
    403 }
    404 
    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 
    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 
    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 //
    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