str_replace_benchmark.cc
Go to the documentation of this file.
00001 // Copyright 2018 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #include "absl/strings/str_replace.h"
00016 
00017 #include <cstring>
00018 #include <string>
00019 
00020 #include "benchmark/benchmark.h"
00021 #include "absl/base/internal/raw_logging.h"
00022 
00023 namespace {
00024 
00025 std::string* big_string;
00026 std::string* after_replacing_the;
00027 std::string* after_replacing_many;
00028 
00029 struct Replacement {
00030   const char* needle;
00031   const char* replacement;
00032 } replacements[] = {
00033     {"the", "box"},          //
00034     {"brown", "quick"},      //
00035     {"jumped", "liquored"},  //
00036     {"dozen", "brown"},      //
00037     {"lazy", "pack"},        //
00038     {"liquor", "shakes"},    //
00039 };
00040 
00041 // Here, we set up a string for use in global-replace benchmarks.
00042 // We started with a million blanks, and then deterministically insert
00043 // 10,000 copies each of two pangrams.  The result is a string that is
00044 // 40% blank space and 60% these words.  'the' occurs 18,247 times and
00045 // all the substitutions together occur 49,004 times.
00046 //
00047 // We then create "after_replacing_the" to be a string that is a result of
00048 // replacing "the" with "box" in big_string.
00049 //
00050 // And then we create "after_replacing_many" to be a string that is result
00051 // of preferring several substitutions.
00052 void SetUpStrings() {
00053   if (big_string == nullptr) {
00054     size_t r = 0;
00055     big_string = new std::string(1000 * 1000, ' ');
00056     for (std::string phrase : {"the quick brown fox jumped over the lazy dogs",
00057                                "pack my box with the five dozen liquor jugs"}) {
00058       for (int i = 0; i < 10 * 1000; ++i) {
00059         r = r * 237 + 41;  // not very random.
00060         memcpy(&(*big_string)[r % (big_string->size() - phrase.size())],
00061                phrase.data(), phrase.size());
00062       }
00063     }
00064     // big_string->resize(50);
00065     // OK, we've set up the std::string, now let's set up expectations - first by
00066     // just replacing "the" with "box"
00067     after_replacing_the = new std::string(*big_string);
00068     for (size_t pos = 0;
00069          (pos = after_replacing_the->find("the", pos)) != std::string::npos;) {
00070       memcpy(&(*after_replacing_the)[pos], "box", 3);
00071     }
00072     // And then with all the replacements.
00073     after_replacing_many = new std::string(*big_string);
00074     for (size_t pos = 0;;) {
00075       size_t next_pos = static_cast<size_t>(-1);
00076       const char* needle_string = nullptr;
00077       const char* replacement_string = nullptr;
00078       for (const auto& r : replacements) {
00079         auto needlepos = after_replacing_many->find(r.needle, pos);
00080         if (needlepos != std::string::npos && needlepos < next_pos) {
00081           next_pos = needlepos;
00082           needle_string = r.needle;
00083           replacement_string = r.replacement;
00084         }
00085       }
00086       if (next_pos > after_replacing_many->size()) break;
00087       after_replacing_many->replace(next_pos, strlen(needle_string),
00088                                     replacement_string);
00089       next_pos += strlen(replacement_string);
00090       pos = next_pos;
00091     }
00092   }
00093 }
00094 
00095 void BM_StrReplaceAllOneReplacement(benchmark::State& state) {
00096   SetUpStrings();
00097   std::string src = *big_string;
00098   for (auto _ : state) {
00099     std::string dest = absl::StrReplaceAll(src, {{"the", "box"}});
00100     ABSL_RAW_CHECK(dest == *after_replacing_the,
00101                    "not benchmarking intended behavior");
00102   }
00103 }
00104 BENCHMARK(BM_StrReplaceAllOneReplacement);
00105 
00106 void BM_StrReplaceAll(benchmark::State& state) {
00107   SetUpStrings();
00108   std::string src = *big_string;
00109   for (auto _ : state) {
00110     std::string dest = absl::StrReplaceAll(src, {{"the", "box"},
00111                                                  {"brown", "quick"},
00112                                                  {"jumped", "liquored"},
00113                                                  {"dozen", "brown"},
00114                                                  {"lazy", "pack"},
00115                                                  {"liquor", "shakes"}});
00116     ABSL_RAW_CHECK(dest == *after_replacing_many,
00117                    "not benchmarking intended behavior");
00118   }
00119 }
00120 BENCHMARK(BM_StrReplaceAll);
00121 
00122 }  // namespace


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15