• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 std::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, ...
IncrementAlternatingSign(int i)30 inline int IncrementAlternatingSign(int i) {
31   return i > 0 ? -i : 1 - i;
32 }
33 
BM_Sum_By_StrCat(benchmark::State & state)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     }
44     benchmark::DoNotOptimize(sum);
45     i = IncrementAlternatingSign(i);
46   }
47 }
48 BENCHMARK(BM_Sum_By_StrCat);
49 
BM_StrCat_By_snprintf(benchmark::State & state)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 
BM_StrCat_By_Strings(benchmark::State & state)60 void BM_StrCat_By_Strings(benchmark::State& state) {
61   int i = 0;
62   for (auto _ : state) {
63     std::string result =
64         std::string(kStringOne) + " " + kStringTwo + ":" + absl::StrCat(i);
65     benchmark::DoNotOptimize(result);
66     i = IncrementAlternatingSign(i);
67   }
68 }
69 BENCHMARK(BM_StrCat_By_Strings);
70 
BM_StrCat_By_StringOpPlus(benchmark::State & state)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);
79     benchmark::DoNotOptimize(result);
80     i = IncrementAlternatingSign(i);
81   }
82 }
83 BENCHMARK(BM_StrCat_By_StringOpPlus);
84 
BM_StrCat_By_StrCat(benchmark::State & state)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);
89     benchmark::DoNotOptimize(result);
90     i = IncrementAlternatingSign(i);
91   }
92 }
93 BENCHMARK(BM_StrCat_By_StrCat);
94 
BM_HexCat_By_StrCat(benchmark::State & state)95 void BM_HexCat_By_StrCat(benchmark::State& state) {
96   int i = 0;
97   for (auto _ : state) {
98     std::string result =
99         absl::StrCat(kStringOne, " ", absl::Hex(int64_t{i} + 0x10000000));
100     benchmark::DoNotOptimize(result);
101     i = IncrementAlternatingSign(i);
102   }
103 }
104 BENCHMARK(BM_HexCat_By_StrCat);
105 
BM_HexCat_By_Substitute(benchmark::State & state)106 void BM_HexCat_By_Substitute(benchmark::State& state) {
107   int i = 0;
108   for (auto _ : state) {
109     std::string result = absl::Substitute(
110         "$0 $1", kStringOne, reinterpret_cast<void*>(int64_t{i} + 0x10000000));
111     benchmark::DoNotOptimize(result);
112     i = IncrementAlternatingSign(i);
113   }
114 }
115 BENCHMARK(BM_HexCat_By_Substitute);
116 
BM_FloatToString_By_StrCat(benchmark::State & state)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});
122     benchmark::DoNotOptimize(result);
123     i = IncrementAlternatingSign(i);
124   }
125 }
126 BENCHMARK(BM_FloatToString_By_StrCat);
127 
BM_DoubleToString_By_SixDigits(benchmark::State & state)128 void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
129   int i = 0;
130   double foo = 0.0;
131   for (auto _ : state) {
132     std::string result =
133         absl::StrCat(absl::SixDigits(foo += 1.001), " != ", int64_t{i});
134     benchmark::DoNotOptimize(result);
135     i = IncrementAlternatingSign(i);
136   }
137 }
138 BENCHMARK(BM_DoubleToString_By_SixDigits);
139 
140 }  // namespace
141