00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/strings/internal/memutil.h"
00016
00017 #include <algorithm>
00018 #include <cstdlib>
00019
00020 #include "benchmark/benchmark.h"
00021 #include "absl/strings/ascii.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 namespace {
00086
00087 constexpr int kHaystackSize = 10000;
00088 constexpr int64_t kHaystackSize64 = kHaystackSize;
00089 const char* MakeHaystack() {
00090 char* haystack = new char[kHaystackSize];
00091 for (int i = 0; i < kHaystackSize - 1; ++i) haystack[i] = 'a';
00092 haystack[kHaystackSize - 1] = 'b';
00093 return haystack;
00094 }
00095 const char* const kHaystack = MakeHaystack();
00096
00097 void BM_Memmem(benchmark::State& state) {
00098 for (auto _ : state) {
00099 benchmark::DoNotOptimize(
00100 absl::strings_internal::memmem(kHaystack, kHaystackSize, "b", 1));
00101 }
00102 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00103 }
00104 BENCHMARK(BM_Memmem);
00105
00106 void BM_MemmemMedium(benchmark::State& state) {
00107 for (auto _ : state) {
00108 benchmark::DoNotOptimize(
00109 absl::strings_internal::memmem(kHaystack, kHaystackSize, "ab", 2));
00110 }
00111 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00112 }
00113 BENCHMARK(BM_MemmemMedium);
00114
00115 void BM_MemmemPathological(benchmark::State& state) {
00116 for (auto _ : state) {
00117 benchmark::DoNotOptimize(absl::strings_internal::memmem(
00118 kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2,
00119 kHaystackSize - kHaystackSize / 2));
00120 }
00121 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00122 }
00123 BENCHMARK(BM_MemmemPathological);
00124
00125 void BM_Memcasemem(benchmark::State& state) {
00126 for (auto _ : state) {
00127 benchmark::DoNotOptimize(
00128 absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "b", 1));
00129 }
00130 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00131 }
00132 BENCHMARK(BM_Memcasemem);
00133
00134 void BM_MemcasememMedium(benchmark::State& state) {
00135 for (auto _ : state) {
00136 benchmark::DoNotOptimize(
00137 absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "ab", 2));
00138 }
00139 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00140 }
00141 BENCHMARK(BM_MemcasememMedium);
00142
00143 void BM_MemcasememPathological(benchmark::State& state) {
00144 for (auto _ : state) {
00145 benchmark::DoNotOptimize(absl::strings_internal::memcasemem(
00146 kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2,
00147 kHaystackSize - kHaystackSize / 2));
00148 }
00149 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00150 }
00151 BENCHMARK(BM_MemcasememPathological);
00152
00153 bool case_eq(const char a, const char b) {
00154 return absl::ascii_tolower(a) == absl::ascii_tolower(b);
00155 }
00156
00157 void BM_Search(benchmark::State& state) {
00158 for (auto _ : state) {
00159 benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
00160 kHaystack + kHaystackSize - 1,
00161 kHaystack + kHaystackSize));
00162 }
00163 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00164 }
00165 BENCHMARK(BM_Search);
00166
00167 void BM_SearchMedium(benchmark::State& state) {
00168 for (auto _ : state) {
00169 benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
00170 kHaystack + kHaystackSize - 2,
00171 kHaystack + kHaystackSize));
00172 }
00173 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00174 }
00175 BENCHMARK(BM_SearchMedium);
00176
00177 void BM_SearchPathological(benchmark::State& state) {
00178 for (auto _ : state) {
00179 benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
00180 kHaystack + kHaystackSize / 2,
00181 kHaystack + kHaystackSize));
00182 }
00183 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00184 }
00185 BENCHMARK(BM_SearchPathological);
00186
00187 void BM_Searchcase(benchmark::State& state) {
00188 for (auto _ : state) {
00189 benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
00190 kHaystack + kHaystackSize - 1,
00191 kHaystack + kHaystackSize, case_eq));
00192 }
00193 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00194 }
00195 BENCHMARK(BM_Searchcase);
00196
00197 void BM_SearchcaseMedium(benchmark::State& state) {
00198 for (auto _ : state) {
00199 benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
00200 kHaystack + kHaystackSize - 2,
00201 kHaystack + kHaystackSize, case_eq));
00202 }
00203 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00204 }
00205 BENCHMARK(BM_SearchcaseMedium);
00206
00207 void BM_SearchcasePathological(benchmark::State& state) {
00208 for (auto _ : state) {
00209 benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize,
00210 kHaystack + kHaystackSize / 2,
00211 kHaystack + kHaystackSize, case_eq));
00212 }
00213 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00214 }
00215 BENCHMARK(BM_SearchcasePathological);
00216
00217 char* memcasechr(const char* s, int c, size_t slen) {
00218 c = absl::ascii_tolower(c);
00219 for (; slen; ++s, --slen) {
00220 if (absl::ascii_tolower(*s) == c) return const_cast<char*>(s);
00221 }
00222 return nullptr;
00223 }
00224
00225 const char* memcasematch(const char* phaystack, size_t haylen,
00226 const char* pneedle, size_t neelen) {
00227 if (0 == neelen) {
00228 return phaystack;
00229 }
00230 if (haylen < neelen) return nullptr;
00231
00232 const char* match;
00233 const char* hayend = phaystack + haylen - neelen + 1;
00234 while ((match = static_cast<char*>(
00235 memcasechr(phaystack, pneedle[0], hayend - phaystack)))) {
00236 if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0)
00237 return match;
00238 else
00239 phaystack = match + 1;
00240 }
00241 return nullptr;
00242 }
00243
00244 void BM_Memmatch(benchmark::State& state) {
00245 for (auto _ : state) {
00246 benchmark::DoNotOptimize(
00247 absl::strings_internal::memmatch(kHaystack, kHaystackSize, "b", 1));
00248 }
00249 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00250 }
00251 BENCHMARK(BM_Memmatch);
00252
00253 void BM_MemmatchMedium(benchmark::State& state) {
00254 for (auto _ : state) {
00255 benchmark::DoNotOptimize(
00256 absl::strings_internal::memmatch(kHaystack, kHaystackSize, "ab", 2));
00257 }
00258 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00259 }
00260 BENCHMARK(BM_MemmatchMedium);
00261
00262 void BM_MemmatchPathological(benchmark::State& state) {
00263 for (auto _ : state) {
00264 benchmark::DoNotOptimize(absl::strings_internal::memmatch(
00265 kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2,
00266 kHaystackSize - kHaystackSize / 2));
00267 }
00268 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00269 }
00270 BENCHMARK(BM_MemmatchPathological);
00271
00272 void BM_Memcasematch(benchmark::State& state) {
00273 for (auto _ : state) {
00274 benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "b", 1));
00275 }
00276 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00277 }
00278 BENCHMARK(BM_Memcasematch);
00279
00280 void BM_MemcasematchMedium(benchmark::State& state) {
00281 for (auto _ : state) {
00282 benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "ab", 2));
00283 }
00284 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00285 }
00286 BENCHMARK(BM_MemcasematchMedium);
00287
00288 void BM_MemcasematchPathological(benchmark::State& state) {
00289 for (auto _ : state) {
00290 benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize,
00291 kHaystack + kHaystackSize / 2,
00292 kHaystackSize - kHaystackSize / 2));
00293 }
00294 state.SetBytesProcessed(kHaystackSize64 * state.iterations());
00295 }
00296 BENCHMARK(BM_MemcasematchPathological);
00297
00298 void BM_MemmemStartup(benchmark::State& state) {
00299 for (auto _ : state) {
00300 benchmark::DoNotOptimize(absl::strings_internal::memmem(
00301 kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1));
00302 }
00303 }
00304 BENCHMARK(BM_MemmemStartup);
00305
00306 void BM_SearchStartup(benchmark::State& state) {
00307 for (auto _ : state) {
00308 benchmark::DoNotOptimize(
00309 std::search(kHaystack + kHaystackSize - 10, kHaystack + kHaystackSize,
00310 kHaystack + kHaystackSize - 1, kHaystack + kHaystackSize));
00311 }
00312 }
00313 BENCHMARK(BM_SearchStartup);
00314
00315 void BM_MemmatchStartup(benchmark::State& state) {
00316 for (auto _ : state) {
00317 benchmark::DoNotOptimize(absl::strings_internal::memmatch(
00318 kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1));
00319 }
00320 }
00321 BENCHMARK(BM_MemmatchStartup);
00322
00323 }