Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
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;
00060 memcpy(&(*big_string)[r % (big_string->size() - phrase.size())],
00061 phrase.data(), phrase.size());
00062 }
00063 }
00064
00065
00066
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
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 }