tor-browser

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

statusor_benchmark.cc (15191B)


      1 // Copyright 2025 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include <string>
     16 
     17 #include "absl/status/status.h"
     18 #include "absl/status/statusor.h"
     19 #include "benchmark/benchmark.h"
     20 
     21 namespace {
     22 
     23 void BM_StatusOrInt_CtorStatus(benchmark::State& state) {
     24  for (auto _ : state) {
     25    absl::StatusOr<int> status(absl::CancelledError());
     26    benchmark::DoNotOptimize(status);
     27  }
     28 }
     29 BENCHMARK(BM_StatusOrInt_CtorStatus);
     30 
     31 void BM_StatusOrInt_CtorStatusWithMessage(benchmark::State& state) {
     32  for (auto _ : state) {
     33    absl::StatusOr<int> status(
     34        absl::UnknownError("This string is 28 characters"));
     35    benchmark::DoNotOptimize(status);
     36  }
     37 }
     38 BENCHMARK(BM_StatusOrInt_CtorStatusWithMessage);
     39 
     40 void BM_StatusOrInt_CopyCtor_Error(benchmark::State& state) {
     41  for (auto _ : state) {
     42    absl::StatusOr<int> original(
     43        absl::UnknownError("This string is 28 characters"));
     44    benchmark::DoNotOptimize(original);
     45    absl::StatusOr<int> status(original);
     46    benchmark::DoNotOptimize(status);
     47  }
     48 }
     49 BENCHMARK(BM_StatusOrInt_CopyCtor_Error);
     50 
     51 void BM_StatusOrInt_CopyCtor_Ok(benchmark::State& state) {
     52  for (auto _ : state) {
     53    absl::StatusOr<int> original(42);
     54    benchmark::DoNotOptimize(original);
     55    absl::StatusOr<int> status(original);
     56    benchmark::DoNotOptimize(status);
     57  }
     58 }
     59 BENCHMARK(BM_StatusOrInt_CopyCtor_Ok);
     60 
     61 void BM_StatusOrInt_MoveCtor_Error(benchmark::State& state) {
     62  for (auto _ : state) {
     63    absl::StatusOr<int> original(
     64        absl::UnknownError("This string is 28 characters"));
     65    benchmark::DoNotOptimize(original);
     66    absl::StatusOr<int> status(std::move(original));
     67    benchmark::DoNotOptimize(status);
     68  }
     69 }
     70 BENCHMARK(BM_StatusOrInt_MoveCtor_Error);
     71 
     72 void BM_StatusOrInt_MoveCtor_Ok(benchmark::State& state) {
     73  for (auto _ : state) {
     74    absl::StatusOr<int> original(42);
     75    benchmark::DoNotOptimize(original);
     76    absl::StatusOr<int> status(std::move(original));
     77    benchmark::DoNotOptimize(status);
     78  }
     79 }
     80 BENCHMARK(BM_StatusOrInt_MoveCtor_Ok);
     81 
     82 void BM_StatusOrInt_CopyAssign_Error(benchmark::State& state) {
     83  for (auto _ : state) {
     84    absl::StatusOr<int> original(
     85        absl::UnknownError("This string is 28 characters"));
     86    benchmark::DoNotOptimize(original);
     87    absl::StatusOr<int> status(42);
     88    benchmark::DoNotOptimize(status);
     89    benchmark::DoNotOptimize(status = original);
     90    benchmark::DoNotOptimize(status);
     91  }
     92 }
     93 BENCHMARK(BM_StatusOrInt_CopyAssign_Error);
     94 
     95 void BM_StatusOrInt_CopyAssign_Ok(benchmark::State& state) {
     96  for (auto _ : state) {
     97    absl::StatusOr<int> original(42);
     98    benchmark::DoNotOptimize(original);
     99    absl::StatusOr<int> status(42);
    100    benchmark::DoNotOptimize(status);
    101    benchmark::DoNotOptimize(status = original);
    102    benchmark::DoNotOptimize(status);
    103  }
    104 }
    105 BENCHMARK(BM_StatusOrInt_CopyAssign_Ok);
    106 
    107 void BM_StatusOrInt_MoveAssign_Error(benchmark::State& state) {
    108  for (auto _ : state) {
    109    absl::StatusOr<int> original(
    110        absl::UnknownError("This string is 28 characters"));
    111    benchmark::DoNotOptimize(original);
    112    absl::StatusOr<int> status(42);
    113    benchmark::DoNotOptimize(status);
    114    benchmark::DoNotOptimize(status = std::move(original));
    115    benchmark::DoNotOptimize(status);
    116  }
    117 }
    118 BENCHMARK(BM_StatusOrInt_MoveAssign_Error);
    119 
    120 void BM_StatusOrInt_MoveAssign_Ok(benchmark::State& state) {
    121  for (auto _ : state) {
    122    absl::StatusOr<int> original(42);
    123    benchmark::DoNotOptimize(original);
    124    absl::StatusOr<int> status(42);
    125    benchmark::DoNotOptimize(status);
    126    benchmark::DoNotOptimize(status = std::move(original));
    127    benchmark::DoNotOptimize(status);
    128  }
    129 }
    130 BENCHMARK(BM_StatusOrInt_MoveAssign_Ok);
    131 
    132 void BM_StatusOrInt_OkMethod_Error(benchmark::State& state) {
    133  absl::StatusOr<int> status(
    134      absl::UnknownError("This string is 28 characters"));
    135  for (auto _ : state) {
    136    benchmark::DoNotOptimize(status);
    137    benchmark::DoNotOptimize(status.ok());
    138  }
    139 }
    140 BENCHMARK(BM_StatusOrInt_OkMethod_Error);
    141 
    142 void BM_StatusOrInt_OkMethod_Ok(benchmark::State& state) {
    143  absl::StatusOr<int> status(42);
    144  for (auto _ : state) {
    145    benchmark::DoNotOptimize(status);
    146    benchmark::DoNotOptimize(status.ok());
    147  }
    148 }
    149 BENCHMARK(BM_StatusOrInt_OkMethod_Ok);
    150 
    151 void BM_StatusOrInt_StatusMethod_Error(benchmark::State& state) {
    152  for (auto _ : state) {
    153    absl::StatusOr<int> status(
    154        absl::UnknownError("This string is 28 characters"));
    155    benchmark::DoNotOptimize(status);
    156    benchmark::DoNotOptimize(status.status().ok());
    157  }
    158 }
    159 BENCHMARK(BM_StatusOrInt_StatusMethod_Error);
    160 
    161 void BM_StatusOrInt_StatusMethod_Ok(benchmark::State& state) {
    162  for (auto _ : state) {
    163    absl::StatusOr<int> status(42);
    164    benchmark::DoNotOptimize(status);
    165    benchmark::DoNotOptimize(std::move(status).status().ok());
    166  }
    167 }
    168 BENCHMARK(BM_StatusOrInt_StatusMethod_Ok);
    169 
    170 void BM_StatusOrInt_StatusMethodRvalue_Error(benchmark::State& state) {
    171  for (auto _ : state) {
    172    absl::StatusOr<int> status(
    173        absl::UnknownError("This string is 28 characters"));
    174    benchmark::DoNotOptimize(status);
    175    benchmark::DoNotOptimize(std::move(status).status().ok());
    176  }
    177 }
    178 BENCHMARK(BM_StatusOrInt_StatusMethodRvalue_Error);
    179 
    180 void BM_StatusOrInt_StatusMethodRvalue_Ok(benchmark::State& state) {
    181  for (auto _ : state) {
    182    absl::StatusOr<int> status(42);
    183    benchmark::DoNotOptimize(status);
    184    benchmark::DoNotOptimize(std::move(status).status());
    185  }
    186 }
    187 BENCHMARK(BM_StatusOrInt_StatusMethodRvalue_Ok);
    188 
    189 void BM_StatusOrString_CtorStatus(benchmark::State& state) {
    190  for (auto _ : state) {
    191    absl::StatusOr<std::string> status(absl::CancelledError());
    192    benchmark::DoNotOptimize(status);
    193  }
    194 }
    195 BENCHMARK(BM_StatusOrString_CtorStatus);
    196 
    197 void BM_StatusOrString_CtorStatusWithMessage(benchmark::State& state) {
    198  for (auto _ : state) {
    199    absl::StatusOr<std::string> status(
    200        absl::UnknownError("This string is 28 characters"));
    201    benchmark::DoNotOptimize(status);
    202  }
    203 }
    204 BENCHMARK(BM_StatusOrString_CtorStatusWithMessage);
    205 
    206 void BM_StatusOrString_CopyCtor_Error(benchmark::State& state) {
    207  for (auto _ : state) {
    208    absl::StatusOr<std::string> original(
    209        absl::UnknownError("This string is 28 characters"));
    210    benchmark::DoNotOptimize(original);
    211    absl::StatusOr<std::string> status(original);
    212    benchmark::DoNotOptimize(status);
    213  }
    214 }
    215 BENCHMARK(BM_StatusOrString_CopyCtor_Error);
    216 
    217 void BM_StatusOrString_CopyCtor_Ok(benchmark::State& state) {
    218  for (auto _ : state) {
    219    absl::StatusOr<std::string> original("This string is 28 characters");
    220    benchmark::DoNotOptimize(original);
    221    absl::StatusOr<std::string> status(original);
    222    benchmark::DoNotOptimize(status);
    223  }
    224 }
    225 BENCHMARK(BM_StatusOrString_CopyCtor_Ok);
    226 
    227 void BM_StatusOrString_MoveCtor_Error(benchmark::State& state) {
    228  for (auto _ : state) {
    229    absl::StatusOr<std::string> original(
    230        absl::UnknownError("This string is 28 characters"));
    231    benchmark::DoNotOptimize(original);
    232    absl::StatusOr<std::string> status(std::move(original));
    233    benchmark::DoNotOptimize(status);
    234  }
    235 }
    236 BENCHMARK(BM_StatusOrString_MoveCtor_Error);
    237 
    238 void BM_StatusOrString_MoveCtor_Ok(benchmark::State& state) {
    239  for (auto _ : state) {
    240    absl::StatusOr<std::string> original("This string is 28 characters");
    241    benchmark::DoNotOptimize(original);
    242    absl::StatusOr<std::string> status(std::move(original));
    243    benchmark::DoNotOptimize(status);
    244  }
    245 }
    246 BENCHMARK(BM_StatusOrString_MoveCtor_Ok);
    247 
    248 void BM_StatusOrString_CopyAssign_Error(benchmark::State& state) {
    249  for (auto _ : state) {
    250    absl::StatusOr<std::string> original(
    251        absl::UnknownError("This string is 28 characters"));
    252    benchmark::DoNotOptimize(original);
    253    absl::StatusOr<std::string> status("This string is 28 characters");
    254    benchmark::DoNotOptimize(status);
    255    benchmark::DoNotOptimize(status = original);
    256    benchmark::DoNotOptimize(status);
    257  }
    258 }
    259 BENCHMARK(BM_StatusOrString_CopyAssign_Error);
    260 
    261 void BM_StatusOrString_CopyAssign_Ok(benchmark::State& state) {
    262  for (auto _ : state) {
    263    absl::StatusOr<std::string> original("This string is 28 characters");
    264    benchmark::DoNotOptimize(original);
    265    absl::StatusOr<std::string> status("This string is 28 characters");
    266    benchmark::DoNotOptimize(status);
    267    benchmark::DoNotOptimize(status = original);
    268    benchmark::DoNotOptimize(status);
    269  }
    270 }
    271 BENCHMARK(BM_StatusOrString_CopyAssign_Ok);
    272 
    273 void BM_StatusOrString_MoveAssign_Error(benchmark::State& state) {
    274  for (auto _ : state) {
    275    absl::StatusOr<std::string> original(
    276        absl::UnknownError("This string is 28 characters"));
    277    benchmark::DoNotOptimize(original);
    278    absl::StatusOr<std::string> status("This string is 28 characters");
    279    benchmark::DoNotOptimize(status);
    280    benchmark::DoNotOptimize(status = std::move(original));
    281    benchmark::DoNotOptimize(status);
    282  }
    283 }
    284 BENCHMARK(BM_StatusOrString_MoveAssign_Error);
    285 
    286 void BM_StatusOrString_MoveAssign_Ok(benchmark::State& state) {
    287  for (auto _ : state) {
    288    absl::StatusOr<std::string> original("This string is 28 characters");
    289    benchmark::DoNotOptimize(original);
    290    absl::StatusOr<std::string> status("This string is 28 characters");
    291    benchmark::DoNotOptimize(status);
    292    benchmark::DoNotOptimize(status = std::move(original));
    293    benchmark::DoNotOptimize(status);
    294  }
    295 }
    296 BENCHMARK(BM_StatusOrString_MoveAssign_Ok);
    297 
    298 void BM_StatusOrString_OkMethod_Error(benchmark::State& state) {
    299  for (auto _ : state) {
    300    absl::StatusOr<std::string> status(
    301        absl::UnknownError("This string is 28 characters"));
    302    benchmark::DoNotOptimize(status);
    303    benchmark::DoNotOptimize(status.ok());
    304  }
    305 }
    306 BENCHMARK(BM_StatusOrString_OkMethod_Error);
    307 
    308 void BM_StatusOrString_OkMethod_Ok(benchmark::State& state) {
    309  for (auto _ : state) {
    310    absl::StatusOr<std::string> status("This string is 28 characters");
    311    benchmark::DoNotOptimize(status);
    312    benchmark::DoNotOptimize(status.ok());
    313  }
    314 }
    315 BENCHMARK(BM_StatusOrString_OkMethod_Ok);
    316 
    317 void BM_StatusOrString_StatusMethod_Error(benchmark::State& state) {
    318  for (auto _ : state) {
    319    absl::StatusOr<std::string> status(
    320        absl::UnknownError("This string is 28 characters"));
    321    benchmark::DoNotOptimize(status);
    322    benchmark::DoNotOptimize(status.status().ok());
    323  }
    324 }
    325 BENCHMARK(BM_StatusOrString_StatusMethod_Error);
    326 
    327 void BM_StatusOrString_StatusMethod_Ok(benchmark::State& state) {
    328  for (auto _ : state) {
    329    absl::StatusOr<std::string> status("This string is 28 characters");
    330    benchmark::DoNotOptimize(status);
    331    benchmark::DoNotOptimize(status.status().ok());
    332  }
    333 }
    334 BENCHMARK(BM_StatusOrString_StatusMethod_Ok);
    335 
    336 void BM_StatusOrString_StatusMethodRvalue_Error(benchmark::State& state) {
    337  for (auto _ : state) {
    338    absl::StatusOr<std::string> status(
    339        absl::UnknownError("This string is 28 characters"));
    340    benchmark::DoNotOptimize(status);
    341    benchmark::DoNotOptimize(std::move(status).status());
    342  }
    343 }
    344 BENCHMARK(BM_StatusOrString_StatusMethodRvalue_Error);
    345 
    346 void BM_StatusOrString_StatusMethodRvalue_Ok(benchmark::State& state) {
    347  for (auto _ : state) {
    348    absl::StatusOr<std::string> status("This string is 28 characters");
    349    benchmark::DoNotOptimize(status);
    350    benchmark::DoNotOptimize(std::move(status).status());
    351  }
    352 }
    353 BENCHMARK(BM_StatusOrString_StatusMethodRvalue_Ok);
    354 
    355 // Benchmarks comparing a few alternative ways of structuring an interface
    356 // for returning an int64 on success or an error.  See (a), (b), (c), (d)
    357 // below for the variants.
    358 bool bm_cond = true;
    359 
    360 bool SimpleIntInterface(int64_t* v) ABSL_ATTRIBUTE_NOINLINE;
    361 bool SimpleIntInterfaceWithErrorMessage(int64_t* v, std::string* msg)
    362    ABSL_ATTRIBUTE_NOINLINE;
    363 absl::Status SimpleIntInterfaceWithErrorStatus(int64_t* v)
    364    ABSL_ATTRIBUTE_NOINLINE;
    365 absl::StatusOr<int64_t> SimpleIntStatusOrInterface() ABSL_ATTRIBUTE_NOINLINE;
    366 
    367 // (a): Just a boolean return value with an out int64* parameter
    368 bool SimpleIntInterface(int64_t* v) {
    369  benchmark::DoNotOptimize(bm_cond);
    370  if (bm_cond) {
    371    *v = 42;
    372    return true;
    373  } else {
    374    return false;
    375  }
    376 }
    377 
    378 // (b): A boolean return value and a string error message filled in on failure
    379 // and an out int64* parameter filled on success
    380 bool SimpleIntInterfaceWithErrorMessage(int64_t* v, std::string* msg) {
    381  benchmark::DoNotOptimize(bm_cond);
    382  if (bm_cond) {
    383    *v = 42;
    384    return true;
    385  } else {
    386    *msg = "This is an error message";
    387    return false;
    388  }
    389 }
    390 
    391 // (c): A Status return value with an out int64* parameter on success
    392 absl::Status SimpleIntInterfaceWithErrorStatus(int64_t* v) {
    393  benchmark::DoNotOptimize(bm_cond);
    394  if (bm_cond) {
    395    *v = 42;
    396    return absl::OkStatus();
    397  } else {
    398    return absl::UnknownError("This is an error message");
    399  }
    400 }
    401 
    402 // (d): A StatusOr<int64> return value
    403 absl::StatusOr<int64_t> SimpleIntStatusOrInterface() {
    404  benchmark::DoNotOptimize(bm_cond);
    405  if (bm_cond) {
    406    return 42;
    407  } else {
    408    return absl::StatusOr<int64_t>(
    409        absl::UnknownError("This is an error message"));
    410  }
    411 }
    412 
    413 void SetCondition(benchmark::State& state) {
    414  bm_cond = (state.range(0) == 0);
    415  state.SetLabel(bm_cond ? "Success" : "Failure");
    416 }
    417 
    418 void BM_SimpleIntInterface(benchmark::State& state) {
    419  SetCondition(state);
    420  int64_t sum = 0;
    421  for (auto s : state) {
    422    int64_t v;
    423    if (SimpleIntInterface(&v)) {
    424      sum += v;
    425    }
    426    benchmark::DoNotOptimize(sum);
    427  }
    428 }
    429 
    430 void BM_SimpleIntInterfaceMsg(benchmark::State& state) {
    431  SetCondition(state);
    432  int64_t sum = 0;
    433  std::string msg;
    434  for (auto s : state) {
    435    int64_t v;
    436    if (SimpleIntInterfaceWithErrorMessage(&v, &msg)) {
    437      sum += v;
    438    }
    439    benchmark::DoNotOptimize(sum);
    440    benchmark::DoNotOptimize(msg);
    441  }
    442 }
    443 
    444 void BM_SimpleIntInterfaceStatus(benchmark::State& state) {
    445  SetCondition(state);
    446  int64_t sum = 0;
    447  for (auto s : state) {
    448    int64_t v;
    449    auto result = SimpleIntInterfaceWithErrorStatus(&v);
    450    if (result.ok()) {
    451      sum += v;
    452    }
    453    benchmark::DoNotOptimize(sum);
    454  }
    455 }
    456 
    457 void BM_SimpleIntStatusOrInterface(benchmark::State& state) {
    458  SetCondition(state);
    459  int64_t sum = 0;
    460  for (auto s : state) {
    461    auto v_s = SimpleIntStatusOrInterface();
    462    if (v_s.ok()) {
    463      sum += *v_s;
    464    }
    465    benchmark::DoNotOptimize(sum);
    466  }
    467 }
    468 
    469 // Ordered like this so all the success path benchmarks (Arg(0)) show up,
    470 // then all the failure benchmarks (Arg(1))
    471 BENCHMARK(BM_SimpleIntInterface)->Arg(0);
    472 BENCHMARK(BM_SimpleIntInterfaceMsg)->Arg(0);
    473 BENCHMARK(BM_SimpleIntInterfaceStatus)->Arg(0);
    474 BENCHMARK(BM_SimpleIntStatusOrInterface)->Arg(0);
    475 BENCHMARK(BM_SimpleIntInterface)->Arg(1);
    476 BENCHMARK(BM_SimpleIntInterfaceMsg)->Arg(1);
    477 BENCHMARK(BM_SimpleIntInterfaceStatus)->Arg(1);
    478 BENCHMARK(BM_SimpleIntStatusOrInterface)->Arg(1);
    479 
    480 }  // namespace