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