tor-browser

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

str_split_benchmark.cc (5861B)


      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 <cstddef>
     16 #include <iterator>
     17 #include <string>
     18 #include <unordered_map>
     19 #include <unordered_set>
     20 #include <vector>
     21 
     22 #include "absl/base/internal/raw_logging.h"
     23 #include "absl/strings/str_split.h"
     24 #include "absl/strings/string_view.h"
     25 #include "benchmark/benchmark.h"
     26 
     27 namespace {
     28 
     29 std::string MakeTestString(int desired_length) {
     30  static const int kAverageValueLen = 25;
     31  std::string test(desired_length * kAverageValueLen, 'x');
     32  for (int i = 1; i < test.size(); i += kAverageValueLen) {
     33    test[i] = ';';
     34  }
     35  return test;
     36 }
     37 
     38 void BM_Split2StringView(benchmark::State& state) {
     39  std::string test = MakeTestString(state.range(0));
     40  for (auto _ : state) {
     41    std::vector<absl::string_view> result = absl::StrSplit(test, ';');
     42    benchmark::DoNotOptimize(result);
     43  }
     44 }
     45 BENCHMARK_RANGE(BM_Split2StringView, 0, 1 << 20);
     46 
     47 static const absl::string_view kDelimiters = ";:,.";
     48 
     49 std::string MakeMultiDelimiterTestString(int desired_length) {
     50  static const int kAverageValueLen = 25;
     51  std::string test(desired_length * kAverageValueLen, 'x');
     52  for (int i = 0; i * kAverageValueLen < test.size(); ++i) {
     53    // Cycle through a variety of delimiters.
     54    test[i * kAverageValueLen] = kDelimiters[i % kDelimiters.size()];
     55  }
     56  return test;
     57 }
     58 
     59 // Measure StrSplit with ByAnyChar with four delimiters to choose from.
     60 void BM_Split2StringViewByAnyChar(benchmark::State& state) {
     61  std::string test = MakeMultiDelimiterTestString(state.range(0));
     62  for (auto _ : state) {
     63    std::vector<absl::string_view> result =
     64        absl::StrSplit(test, absl::ByAnyChar(kDelimiters));
     65    benchmark::DoNotOptimize(result);
     66  }
     67 }
     68 BENCHMARK_RANGE(BM_Split2StringViewByAnyChar, 0, 1 << 20);
     69 
     70 void BM_Split2StringViewLifted(benchmark::State& state) {
     71  std::string test = MakeTestString(state.range(0));
     72  std::vector<absl::string_view> result;
     73  for (auto _ : state) {
     74    result = absl::StrSplit(test, ';');
     75  }
     76  benchmark::DoNotOptimize(result);
     77 }
     78 BENCHMARK_RANGE(BM_Split2StringViewLifted, 0, 1 << 20);
     79 
     80 void BM_Split2String(benchmark::State& state) {
     81  std::string test = MakeTestString(state.range(0));
     82  for (auto _ : state) {
     83    std::vector<std::string> result = absl::StrSplit(test, ';');
     84    benchmark::DoNotOptimize(result);
     85  }
     86 }
     87 BENCHMARK_RANGE(BM_Split2String, 0, 1 << 20);
     88 
     89 // This benchmark is for comparing Split2 to Split1 (SplitStringUsing). In
     90 // particular, this benchmark uses SkipEmpty() to match SplitStringUsing's
     91 // behavior.
     92 void BM_Split2SplitStringUsing(benchmark::State& state) {
     93  std::string test = MakeTestString(state.range(0));
     94  for (auto _ : state) {
     95    std::vector<std::string> result =
     96        absl::StrSplit(test, ';', absl::SkipEmpty());
     97    benchmark::DoNotOptimize(result);
     98  }
     99 }
    100 BENCHMARK_RANGE(BM_Split2SplitStringUsing, 0, 1 << 20);
    101 
    102 void BM_SplitStringToUnorderedSet(benchmark::State& state) {
    103  const int len = state.range(0);
    104  std::string test(len, 'x');
    105  for (int i = 1; i < len; i += 2) {
    106    test[i] = ';';
    107  }
    108  for (auto _ : state) {
    109    std::unordered_set<std::string> result =
    110        absl::StrSplit(test, ':', absl::SkipEmpty());
    111    benchmark::DoNotOptimize(result);
    112  }
    113 }
    114 BENCHMARK_RANGE(BM_SplitStringToUnorderedSet, 0, 1 << 20);
    115 
    116 void BM_SplitStringToUnorderedMap(benchmark::State& state) {
    117  const int len = state.range(0);
    118  std::string test(len, 'x');
    119  for (int i = 1; i < len; i += 2) {
    120    test[i] = ';';
    121  }
    122  for (auto _ : state) {
    123    std::unordered_map<std::string, std::string> result =
    124        absl::StrSplit(test, ':', absl::SkipEmpty());
    125    benchmark::DoNotOptimize(result);
    126  }
    127 }
    128 BENCHMARK_RANGE(BM_SplitStringToUnorderedMap, 0, 1 << 20);
    129 
    130 void BM_SplitStringAllowEmpty(benchmark::State& state) {
    131  const int len = state.range(0);
    132  std::string test(len, 'x');
    133  for (int i = 1; i < len; i += 2) {
    134    test[i] = ';';
    135  }
    136  for (auto _ : state) {
    137    std::vector<std::string> result = absl::StrSplit(test, ';');
    138    benchmark::DoNotOptimize(result);
    139  }
    140 }
    141 BENCHMARK_RANGE(BM_SplitStringAllowEmpty, 0, 1 << 20);
    142 
    143 struct OneCharLiteral {
    144  char operator()() const { return 'X'; }
    145 };
    146 
    147 struct OneCharStringLiteral {
    148  const char* operator()() const { return "X"; }
    149 };
    150 
    151 template <typename DelimiterFactory>
    152 void BM_SplitStringWithOneChar(benchmark::State& state) {
    153  const auto delimiter = DelimiterFactory()();
    154  std::vector<absl::string_view> pieces;
    155  size_t v = 0;
    156  for (auto _ : state) {
    157    pieces = absl::StrSplit("The quick brown fox jumps over the lazy dog",
    158                            delimiter);
    159    v += pieces.size();
    160  }
    161  ABSL_RAW_CHECK(v == state.iterations(), "");
    162 }
    163 BENCHMARK_TEMPLATE(BM_SplitStringWithOneChar, OneCharLiteral);
    164 BENCHMARK_TEMPLATE(BM_SplitStringWithOneChar, OneCharStringLiteral);
    165 
    166 template <typename DelimiterFactory>
    167 void BM_SplitStringWithOneCharNoVector(benchmark::State& state) {
    168  const auto delimiter = DelimiterFactory()();
    169  size_t v = 0;
    170  for (auto _ : state) {
    171    auto splitter = absl::StrSplit(
    172        "The quick brown fox jumps over the lazy dog", delimiter);
    173    v += std::distance(splitter.begin(), splitter.end());
    174  }
    175  ABSL_RAW_CHECK(v == state.iterations(), "");
    176 }
    177 BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharLiteral);
    178 BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharStringLiteral);
    179 
    180 }  // namespace