tor-browser

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

ascii_benchmark.cc (5303B)


      1 // Copyright 2018 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 <algorithm>
     16 #include <array>
     17 #include <cctype>
     18 #include <cstddef>
     19 #include <random>
     20 #include <string>
     21 
     22 #include "absl/strings/ascii.h"
     23 #include "benchmark/benchmark.h"
     24 
     25 namespace {
     26 
     27 std::array<unsigned char, 256> MakeShuffledBytes() {
     28  std::array<unsigned char, 256> bytes;
     29  for (size_t i = 0; i < 256; ++i) bytes[i] = static_cast<unsigned char>(i);
     30  std::random_device rd;
     31  std::seed_seq seed({rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()});
     32  std::mt19937 g(seed);
     33  std::shuffle(bytes.begin(), bytes.end(), g);
     34  return bytes;
     35 }
     36 
     37 template <typename Function>
     38 void AsciiBenchmark(benchmark::State& state, Function f) {
     39  std::array<unsigned char, 256> bytes = MakeShuffledBytes();
     40  size_t sum = 0;
     41  for (auto _ : state) {
     42    for (unsigned char b : bytes) sum += f(b) ? 1 : 0;
     43  }
     44  // Make a copy of `sum` before calling `DoNotOptimize` to make sure that `sum`
     45  // can be put in a CPU register and not degrade performance in the loop above.
     46  size_t sum2 = sum;
     47  benchmark::DoNotOptimize(sum2);
     48  state.SetBytesProcessed(state.iterations() * bytes.size());
     49 }
     50 
     51 using StdAsciiFunction = int (*)(int);
     52 template <StdAsciiFunction f>
     53 void BM_Ascii(benchmark::State& state) {
     54  AsciiBenchmark(state, f);
     55 }
     56 
     57 using AbslAsciiIsFunction = bool (*)(unsigned char);
     58 template <AbslAsciiIsFunction f>
     59 void BM_Ascii(benchmark::State& state) {
     60  AsciiBenchmark(state, f);
     61 }
     62 
     63 using AbslAsciiToFunction = char (*)(unsigned char);
     64 template <AbslAsciiToFunction f>
     65 void BM_Ascii(benchmark::State& state) {
     66  AsciiBenchmark(state, f);
     67 }
     68 
     69 inline char Noop(unsigned char b) { return static_cast<char>(b); }
     70 
     71 BENCHMARK_TEMPLATE(BM_Ascii, Noop);
     72 BENCHMARK_TEMPLATE(BM_Ascii, std::isalpha);
     73 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isalpha);
     74 BENCHMARK_TEMPLATE(BM_Ascii, std::isdigit);
     75 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isdigit);
     76 BENCHMARK_TEMPLATE(BM_Ascii, std::isalnum);
     77 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isalnum);
     78 BENCHMARK_TEMPLATE(BM_Ascii, std::isspace);
     79 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isspace);
     80 BENCHMARK_TEMPLATE(BM_Ascii, std::ispunct);
     81 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_ispunct);
     82 BENCHMARK_TEMPLATE(BM_Ascii, std::isblank);
     83 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isblank);
     84 BENCHMARK_TEMPLATE(BM_Ascii, std::iscntrl);
     85 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_iscntrl);
     86 BENCHMARK_TEMPLATE(BM_Ascii, std::isxdigit);
     87 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isxdigit);
     88 BENCHMARK_TEMPLATE(BM_Ascii, std::isprint);
     89 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isprint);
     90 BENCHMARK_TEMPLATE(BM_Ascii, std::isgraph);
     91 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isgraph);
     92 BENCHMARK_TEMPLATE(BM_Ascii, std::isupper);
     93 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isupper);
     94 BENCHMARK_TEMPLATE(BM_Ascii, std::islower);
     95 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_islower);
     96 BENCHMARK_TEMPLATE(BM_Ascii, isascii);
     97 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isascii);
     98 BENCHMARK_TEMPLATE(BM_Ascii, std::tolower);
     99 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_tolower);
    100 BENCHMARK_TEMPLATE(BM_Ascii, std::toupper);
    101 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_toupper);
    102 
    103 static void BM_StrToLower(benchmark::State& state) {
    104  const size_t size = static_cast<size_t>(state.range(0));
    105  std::string s(size, 'X');
    106  for (auto _ : state) {
    107    benchmark::DoNotOptimize(s);
    108    std::string res = absl::AsciiStrToLower(s);
    109    benchmark::DoNotOptimize(res);
    110  }
    111 }
    112 BENCHMARK(BM_StrToLower)
    113    ->DenseRange(0, 32)
    114    ->RangeMultiplier(2)
    115    ->Range(64, 1 << 26);
    116 
    117 static void BM_StrToUpper(benchmark::State& state) {
    118  const size_t size = static_cast<size_t>(state.range(0));
    119  std::string s(size, 'x');
    120  for (auto _ : state) {
    121    benchmark::DoNotOptimize(s);
    122    std::string res = absl::AsciiStrToUpper(s);
    123    benchmark::DoNotOptimize(res);
    124  }
    125 }
    126 BENCHMARK(BM_StrToUpper)
    127    ->DenseRange(0, 32)
    128    ->RangeMultiplier(2)
    129    ->Range(64, 1 << 26);
    130 
    131 static void BM_StrToUpperFromRvalref(benchmark::State& state) {
    132  const size_t size = static_cast<size_t>(state.range(0));
    133  std::string s(size, 'X');
    134  for (auto _ : state) {
    135    benchmark::DoNotOptimize(s);
    136    std::string res = absl::AsciiStrToUpper(std::string(s));
    137    benchmark::DoNotOptimize(res);
    138  }
    139 }
    140 BENCHMARK(BM_StrToUpperFromRvalref)
    141    ->DenseRange(0, 32)
    142    ->RangeMultiplier(2)
    143    ->Range(64, 1 << 26);
    144 
    145 static void BM_StrToLowerFromRvalref(benchmark::State& state) {
    146  const size_t size = static_cast<size_t>(state.range(0));
    147  std::string s(size, 'x');
    148  for (auto _ : state) {
    149    benchmark::DoNotOptimize(s);
    150    std::string res = absl::AsciiStrToLower(std::string(s));
    151    benchmark::DoNotOptimize(res);
    152  }
    153 }
    154 BENCHMARK(BM_StrToLowerFromRvalref)
    155    ->DenseRange(0, 32)
    156    ->RangeMultiplier(2)
    157    ->Range(64, 1 << 26);
    158 
    159 }  // namespace