abseil-cpp/absl/strings/str_cat_benchmark.cc
Go to the documentation of this file.
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 "absl/strings/str_cat.h"
16 
17 #include <cstdint>
18 #include <string>
19 
20 #include "benchmark/benchmark.h"
21 #include "absl/strings/substitute.h"
22 
23 namespace {
24 
25 const char kStringOne[] = "Once Upon A Time, ";
26 const char kStringTwo[] = "There was a string benchmark";
27 
28 // We want to include negative numbers in the benchmark, so this function
29 // is used to count 0, 1, -1, 2, -2, 3, -3, ...
30 inline int IncrementAlternatingSign(int i) {
31  return i > 0 ? -i : 1 - i;
32 }
33 
34 void BM_Sum_By_StrCat(benchmark::State& state) {
35  int i = 0;
36  char foo[100];
37  for (auto _ : state) {
38  // NOLINTNEXTLINE(runtime/printf)
39  strcpy(foo, absl::StrCat(kStringOne, i, kStringTwo, i * 65536ULL).c_str());
40  int sum = 0;
41  for (char* f = &foo[0]; *f != 0; ++f) {
42  sum += *f;
43  }
45  i = IncrementAlternatingSign(i);
46  }
47 }
48 BENCHMARK(BM_Sum_By_StrCat);
49 
50 void BM_StrCat_By_snprintf(benchmark::State& state) {
51  int i = 0;
52  char on_stack[1000];
53  for (auto _ : state) {
54  snprintf(on_stack, sizeof(on_stack), "%s %s:%d", kStringOne, kStringTwo, i);
55  i = IncrementAlternatingSign(i);
56  }
57 }
58 BENCHMARK(BM_StrCat_By_snprintf);
59 
60 void BM_StrCat_By_Strings(benchmark::State& state) {
61  int i = 0;
62  for (auto _ : state) {
64  std::string(kStringOne) + " " + kStringTwo + ":" + absl::StrCat(i);
66  i = IncrementAlternatingSign(i);
67  }
68 }
69 BENCHMARK(BM_StrCat_By_Strings);
70 
71 void BM_StrCat_By_StringOpPlus(benchmark::State& state) {
72  int i = 0;
73  for (auto _ : state) {
74  std::string result = kStringOne;
75  result += " ";
76  result += kStringTwo;
77  result += ":";
78  result += absl::StrCat(i);
80  i = IncrementAlternatingSign(i);
81  }
82 }
83 BENCHMARK(BM_StrCat_By_StringOpPlus);
84 
85 void BM_StrCat_By_StrCat(benchmark::State& state) {
86  int i = 0;
87  for (auto _ : state) {
88  std::string result = absl::StrCat(kStringOne, " ", kStringTwo, ":", i);
90  i = IncrementAlternatingSign(i);
91  }
92 }
93 BENCHMARK(BM_StrCat_By_StrCat);
94 
95 void BM_HexCat_By_StrCat(benchmark::State& state) {
96  int i = 0;
97  for (auto _ : state) {
99  absl::StrCat(kStringOne, " ", absl::Hex(int64_t{i} + 0x10000000));
101  i = IncrementAlternatingSign(i);
102  }
103 }
104 BENCHMARK(BM_HexCat_By_StrCat);
105 
106 void BM_HexCat_By_Substitute(benchmark::State& state) {
107  int i = 0;
108  for (auto _ : state) {
110  "$0 $1", kStringOne, reinterpret_cast<void*>(int64_t{i} + 0x10000000));
112  i = IncrementAlternatingSign(i);
113  }
114 }
115 BENCHMARK(BM_HexCat_By_Substitute);
116 
117 void BM_FloatToString_By_StrCat(benchmark::State& state) {
118  int i = 0;
119  float foo = 0.0f;
120  for (auto _ : state) {
121  std::string result = absl::StrCat(foo += 1.001f, " != ", int64_t{i});
123  i = IncrementAlternatingSign(i);
124  }
125 }
126 BENCHMARK(BM_FloatToString_By_StrCat);
127 
128 void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
129  int i = 0;
130  double foo = 0.0;
131  for (auto _ : state) {
133  absl::StrCat(absl::SixDigits(foo += 1.001), " != ", int64_t{i});
135  i = IncrementAlternatingSign(i);
136  }
137 }
138 BENCHMARK(BM_DoubleToString_By_SixDigits);
139 
140 template <typename... Chunks>
141 void BM_StrAppendImpl(benchmark::State& state, size_t total_bytes,
142  Chunks... chunks) {
143  for (auto s : state) {
145  while (result.size() < total_bytes) {
146  absl::StrAppend(&result, chunks...);
148  }
149  }
150 }
151 
152 void BM_StrAppend(benchmark::State& state) {
153  const int total_bytes = state.range(0);
154  const int chunks_at_a_time = state.range(1);
155  const absl::string_view kChunk = "0123456789";
156 
157  switch (chunks_at_a_time) {
158  case 1:
159  return BM_StrAppendImpl(state, total_bytes, kChunk);
160  case 2:
161  return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk);
162  case 4:
163  return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk,
164  kChunk);
165  case 8:
166  return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk,
167  kChunk, kChunk, kChunk, kChunk, kChunk);
168  default:
169  std::abort();
170  }
171 }
172 
173 template <typename B>
174 void StrAppendConfig(B* benchmark) {
175  for (int bytes : {10, 100, 1000, 10000}) {
176  for (int chunks : {1, 2, 4, 8}) {
177  // Only add the ones that divide properly. Otherwise we are over counting.
178  if (bytes % (10 * chunks) == 0) {
179  benchmark->Args({bytes, chunks});
180  }
181  }
182  }
183 }
184 
185 BENCHMARK(BM_StrAppend)->Apply(StrAppendConfig);
186 
187 } // namespace
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
absl::StrAppend
void StrAppend(std::string *dest, const AlphaNum &a)
Definition: abseil-cpp/absl/strings/str_cat.cc:193
benchmark
Definition: bm_alarm.cc:55
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
grpc::testing::sum
double sum(const T &container, F functor)
Definition: test/cpp/qps/stats.h:30
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
foo
Definition: bloaty/third_party/googletest/googletest/test/googletest-output-test_.cc:546
benchmark::DoNotOptimize
BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const &value)
Definition: benchmark/include/benchmark/benchmark.h:375
ULL
#define ULL(x)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:57
absl::Hex
Definition: abseil-cpp/absl/strings/str_cat.h:134
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
gmock_output_test._
_
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
absl::SixDigits
strings_internal::AlphaNumBuffer< numbers_internal::kSixDigitsToBufferSize > SixDigits(double d)
Definition: abseil-cpp/absl/strings/str_cat.h:405
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
benchmark::State
Definition: benchmark/include/benchmark/benchmark.h:503
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
absl::Substitute
ABSL_MUST_USE_RESULT std::string Substitute(absl::string_view format)
Definition: abseil-cpp/absl/strings/substitute.h:506
BENCHMARK
#define BENCHMARK(n)
Definition: benchmark/include/benchmark/benchmark.h:1170
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:19