tor-browser

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

crc32c_benchmark.cc (5987B)


      1 // Copyright 2022 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/crc/crc32c.h"
     18 #include "absl/crc/internal/crc32c.h"
     19 #include "absl/memory/memory.h"
     20 #include "absl/strings/string_view.h"
     21 #include "benchmark/benchmark.h"
     22 
     23 namespace {
     24 
     25 std::string TestString(size_t len) {
     26  std::string result;
     27  result.reserve(len);
     28  for (size_t i = 0; i < len; ++i) {
     29    result.push_back(static_cast<char>(i % 256));
     30  }
     31  return result;
     32 }
     33 
     34 void BM_Calculate(benchmark::State& state) {
     35  int len = state.range(0);
     36  std::string data = TestString(len);
     37  for (auto s : state) {
     38    benchmark::DoNotOptimize(data);
     39    absl::crc32c_t crc = absl::ComputeCrc32c(data);
     40    benchmark::DoNotOptimize(crc);
     41  }
     42 }
     43 BENCHMARK(BM_Calculate)
     44    ->Arg(0)
     45    ->Arg(1)
     46    ->Arg(100)
     47    ->Arg(2048)
     48    ->Arg(10000)
     49    ->Arg(500000);
     50 
     51 void BM_Extend(benchmark::State& state) {
     52  int len = state.range(0);
     53  std::string extension = TestString(len);
     54  absl::crc32c_t base = absl::crc32c_t{0xC99465AA};  // CRC32C of "Hello World"
     55  for (auto s : state) {
     56    benchmark::DoNotOptimize(base);
     57    benchmark::DoNotOptimize(extension);
     58    absl::crc32c_t crc = absl::ExtendCrc32c(base, extension);
     59    benchmark::DoNotOptimize(crc);
     60  }
     61 }
     62 BENCHMARK(BM_Extend)
     63    ->Arg(0)
     64    ->Arg(1)
     65    ->Arg(100)
     66    ->Arg(2048)
     67    ->Arg(10000)
     68    ->Arg(500000)
     69    ->Arg(100 * 1000 * 1000);
     70 
     71 // Make working set >> CPU cache size to benchmark prefetches better
     72 void BM_ExtendCacheMiss(benchmark::State& state) {
     73  int len = state.range(0);
     74  constexpr int total = 300 * 1000 * 1000;
     75  std::string extension = TestString(total);
     76  absl::crc32c_t base = absl::crc32c_t{0xC99465AA};  // CRC32C of "Hello World"
     77  for (auto s : state) {
     78    for (int i = 0; i < total; i += len * 2) {
     79      benchmark::DoNotOptimize(base);
     80      benchmark::DoNotOptimize(extension);
     81      absl::crc32c_t crc =
     82          absl::ExtendCrc32c(base, absl::string_view(&extension[i], len));
     83      benchmark::DoNotOptimize(crc);
     84    }
     85  }
     86  state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) * total / 2);
     87 }
     88 BENCHMARK(BM_ExtendCacheMiss)->Arg(10)->Arg(100)->Arg(1000)->Arg(100000);
     89 
     90 void BM_ExtendByZeroes(benchmark::State& state) {
     91  absl::crc32c_t base = absl::crc32c_t{0xC99465AA};  // CRC32C of "Hello World"
     92  int num_zeroes = state.range(0);
     93  for (auto s : state) {
     94    benchmark::DoNotOptimize(base);
     95    absl::crc32c_t crc = absl::ExtendCrc32cByZeroes(base, num_zeroes);
     96    benchmark::DoNotOptimize(crc);
     97  }
     98 }
     99 BENCHMARK(BM_ExtendByZeroes)
    100    ->RangeMultiplier(10)
    101    ->Range(1, 1000000)
    102    ->RangeMultiplier(32)
    103    ->Range(1, 1 << 20);
    104 
    105 void BM_UnextendByZeroes(benchmark::State& state) {
    106  absl::crc32c_t base = absl::crc32c_t{0xdeadbeef};
    107  int num_zeroes = state.range(0);
    108  for (auto s : state) {
    109    benchmark::DoNotOptimize(base);
    110    absl::crc32c_t crc =
    111        absl::crc_internal::UnextendCrc32cByZeroes(base, num_zeroes);
    112    benchmark::DoNotOptimize(crc);
    113  }
    114 }
    115 BENCHMARK(BM_UnextendByZeroes)
    116    ->RangeMultiplier(10)
    117    ->Range(1, 1000000)
    118    ->RangeMultiplier(32)
    119    ->Range(1, 1 << 20);
    120 
    121 void BM_Concat(benchmark::State& state) {
    122  int string_b_len = state.range(0);
    123  std::string string_b = TestString(string_b_len);
    124 
    125  // CRC32C of "Hello World"
    126  absl::crc32c_t crc_a = absl::crc32c_t{0xC99465AA};
    127  absl::crc32c_t crc_b = absl::ComputeCrc32c(string_b);
    128 
    129  for (auto s : state) {
    130    benchmark::DoNotOptimize(crc_a);
    131    benchmark::DoNotOptimize(crc_b);
    132    benchmark::DoNotOptimize(string_b_len);
    133    absl::crc32c_t crc_ab = absl::ConcatCrc32c(crc_a, crc_b, string_b_len);
    134    benchmark::DoNotOptimize(crc_ab);
    135  }
    136 }
    137 BENCHMARK(BM_Concat)
    138    ->RangeMultiplier(10)
    139    ->Range(1, 1000000)
    140    ->RangeMultiplier(32)
    141    ->Range(1, 1 << 20);
    142 
    143 void BM_Memcpy(benchmark::State& state) {
    144  int string_len = state.range(0);
    145 
    146  std::string source = TestString(string_len);
    147  auto dest = absl::make_unique<char[]>(string_len);
    148 
    149  for (auto s : state) {
    150    benchmark::DoNotOptimize(source);
    151    absl::crc32c_t crc =
    152        absl::MemcpyCrc32c(dest.get(), source.data(), source.size());
    153    benchmark::DoNotOptimize(crc);
    154    benchmark::DoNotOptimize(dest);
    155    benchmark::DoNotOptimize(dest.get());
    156    benchmark::DoNotOptimize(dest[0]);
    157  }
    158 
    159  state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
    160                          state.range(0));
    161 }
    162 BENCHMARK(BM_Memcpy)->Arg(0)->Arg(1)->Arg(100)->Arg(2048)->Arg(10000)->Arg(
    163    500000);
    164 
    165 void BM_RemoveSuffix(benchmark::State& state) {
    166  int full_string_len = state.range(0);
    167  int suffix_len = state.range(1);
    168 
    169  std::string full_string = TestString(full_string_len);
    170  std::string suffix = full_string.substr(
    171    full_string_len - suffix_len, full_string_len);
    172 
    173  absl::crc32c_t full_string_crc = absl::ComputeCrc32c(full_string);
    174  absl::crc32c_t suffix_crc = absl::ComputeCrc32c(suffix);
    175 
    176  for (auto s : state) {
    177    benchmark::DoNotOptimize(full_string_crc);
    178    benchmark::DoNotOptimize(suffix_crc);
    179    benchmark::DoNotOptimize(suffix_len);
    180    absl::crc32c_t crc = absl::RemoveCrc32cSuffix(full_string_crc, suffix_crc,
    181      suffix_len);
    182    benchmark::DoNotOptimize(crc);
    183  }
    184 }
    185 BENCHMARK(BM_RemoveSuffix)
    186    ->ArgPair(1, 1)
    187    ->ArgPair(100, 10)
    188    ->ArgPair(100, 100)
    189    ->ArgPair(10000, 1)
    190    ->ArgPair(10000, 100)
    191    ->ArgPair(10000, 10000)
    192    ->ArgPair(500000, 1)
    193    ->ArgPair(500000, 100)
    194    ->ArgPair(500000, 10000)
    195    ->ArgPair(500000, 500000);
    196 }  // namespace