numbers_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 <cstdint>
16 #include <random>
17 #include <string>
18 #include <type_traits>
19 #include <vector>
20 
21 #include "benchmark/benchmark.h"
23 #include "absl/strings/numbers.h"
24 
25 namespace {
26 
27 template <typename T>
28 void BM_FastIntToBuffer(benchmark::State& state) {
29  const int inc = state.range(0);
31  // Use the unsigned type to increment to take advantage of well-defined
32  // modular arithmetic.
33  typename std::make_unsigned<T>::type x = 0;
34  for (auto _ : state) {
35  absl::numbers_internal::FastIntToBuffer(static_cast<T>(x), buf);
36  x += inc;
37  }
38 }
39 BENCHMARK_TEMPLATE(BM_FastIntToBuffer, int32_t)->Range(0, 1 << 15);
40 BENCHMARK_TEMPLATE(BM_FastIntToBuffer, int64_t)->Range(0, 1 << 30);
41 
42 // Creates an integer that would be printed as `num_digits` repeated 7s in the
43 // given `base`. `base` must be greater than or equal to 8.
44 int64_t RepeatedSevens(int num_digits, int base) {
45  ABSL_RAW_CHECK(base >= 8, "");
46  int64_t num = 7;
47  while (--num_digits) num = base * num + 7;
48  return num;
49 }
50 
51 void BM_safe_strto32_string(benchmark::State& state) {
52  const int digits = state.range(0);
53  const int base = state.range(1);
54  std::string str(digits, '7'); // valid in octal, decimal and hex
55  int32_t value = 0;
56  for (auto _ : state) {
57  benchmark::DoNotOptimize(
59  }
60  ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
61 }
62 BENCHMARK(BM_safe_strto32_string)
63  ->ArgPair(1, 8)
64  ->ArgPair(1, 10)
65  ->ArgPair(1, 16)
66  ->ArgPair(2, 8)
67  ->ArgPair(2, 10)
68  ->ArgPair(2, 16)
69  ->ArgPair(4, 8)
70  ->ArgPair(4, 10)
71  ->ArgPair(4, 16)
72  ->ArgPair(8, 8)
73  ->ArgPair(8, 10)
74  ->ArgPair(8, 16)
75  ->ArgPair(10, 8)
76  ->ArgPair(9, 10);
77 
78 void BM_safe_strto64_string(benchmark::State& state) {
79  const int digits = state.range(0);
80  const int base = state.range(1);
81  std::string str(digits, '7'); // valid in octal, decimal and hex
82  int64_t value = 0;
83  for (auto _ : state) {
84  benchmark::DoNotOptimize(
86  }
87  ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
88 }
89 BENCHMARK(BM_safe_strto64_string)
90  ->ArgPair(1, 8)
91  ->ArgPair(1, 10)
92  ->ArgPair(1, 16)
93  ->ArgPair(2, 8)
94  ->ArgPair(2, 10)
95  ->ArgPair(2, 16)
96  ->ArgPair(4, 8)
97  ->ArgPair(4, 10)
98  ->ArgPair(4, 16)
99  ->ArgPair(8, 8)
100  ->ArgPair(8, 10)
101  ->ArgPair(8, 16)
102  ->ArgPair(16, 8)
103  ->ArgPair(16, 10)
104  ->ArgPair(16, 16);
105 
106 void BM_safe_strtou32_string(benchmark::State& state) {
107  const int digits = state.range(0);
108  const int base = state.range(1);
109  std::string str(digits, '7'); // valid in octal, decimal and hex
110  uint32_t value = 0;
111  for (auto _ : state) {
112  benchmark::DoNotOptimize(
113  absl::numbers_internal::safe_strtou32_base(str, &value, base));
114  }
115  ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
116 }
117 BENCHMARK(BM_safe_strtou32_string)
118  ->ArgPair(1, 8)
119  ->ArgPair(1, 10)
120  ->ArgPair(1, 16)
121  ->ArgPair(2, 8)
122  ->ArgPair(2, 10)
123  ->ArgPair(2, 16)
124  ->ArgPair(4, 8)
125  ->ArgPair(4, 10)
126  ->ArgPair(4, 16)
127  ->ArgPair(8, 8)
128  ->ArgPair(8, 10)
129  ->ArgPair(8, 16)
130  ->ArgPair(10, 8)
131  ->ArgPair(9, 10);
132 
133 void BM_safe_strtou64_string(benchmark::State& state) {
134  const int digits = state.range(0);
135  const int base = state.range(1);
136  std::string str(digits, '7'); // valid in octal, decimal and hex
137  uint64_t value = 0;
138  for (auto _ : state) {
139  benchmark::DoNotOptimize(
140  absl::numbers_internal::safe_strtou64_base(str, &value, base));
141  }
142  ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
143 }
144 BENCHMARK(BM_safe_strtou64_string)
145  ->ArgPair(1, 8)
146  ->ArgPair(1, 10)
147  ->ArgPair(1, 16)
148  ->ArgPair(2, 8)
149  ->ArgPair(2, 10)
150  ->ArgPair(2, 16)
151  ->ArgPair(4, 8)
152  ->ArgPair(4, 10)
153  ->ArgPair(4, 16)
154  ->ArgPair(8, 8)
155  ->ArgPair(8, 10)
156  ->ArgPair(8, 16)
157  ->ArgPair(16, 8)
158  ->ArgPair(16, 10)
159  ->ArgPair(16, 16);
160 
161 // Returns a vector of `num_strings` strings. Each string represents a
162 // floating point number with `num_digits` digits before the decimal point and
163 // another `num_digits` digits after.
164 std::vector<std::string> MakeFloatStrings(int num_strings, int num_digits) {
165  // For convenience, use a random number generator to generate the test data.
166  // We don't actually need random properties, so use a fixed seed.
167  std::minstd_rand0 rng(1);
168  std::uniform_int_distribution<int> random_digit('0', '9');
169 
170  std::vector<std::string> float_strings(num_strings);
171  for (std::string& s : float_strings) {
172  s.reserve(2 * num_digits + 1);
173  for (int i = 0; i < num_digits; ++i) {
174  s.push_back(static_cast<char>(random_digit(rng)));
175  }
176  s.push_back('.');
177  for (int i = 0; i < num_digits; ++i) {
178  s.push_back(static_cast<char>(random_digit(rng)));
179  }
180  }
181  return float_strings;
182 }
183 
184 template <typename StringType>
185 StringType GetStringAs(const std::string& s) {
186  return static_cast<StringType>(s);
187 }
188 template <>
189 const char* GetStringAs<const char*>(const std::string& s) {
190  return s.c_str();
191 }
192 
193 template <typename StringType>
194 std::vector<StringType> GetStringsAs(const std::vector<std::string>& strings) {
195  std::vector<StringType> result;
196  result.reserve(strings.size());
197  for (const std::string& s : strings) {
198  result.push_back(GetStringAs<StringType>(s));
199  }
200  return result;
201 }
202 
203 template <typename T>
204 void BM_SimpleAtof(benchmark::State& state) {
205  const int num_strings = state.range(0);
206  const int num_digits = state.range(1);
207  std::vector<std::string> backing_strings =
208  MakeFloatStrings(num_strings, num_digits);
209  std::vector<T> inputs = GetStringsAs<T>(backing_strings);
210  float value;
211  for (auto _ : state) {
212  for (const T& input : inputs) {
213  benchmark::DoNotOptimize(absl::SimpleAtof(input, &value));
214  }
215  }
216 }
217 BENCHMARK_TEMPLATE(BM_SimpleAtof, absl::string_view)
218  ->ArgPair(10, 1)
219  ->ArgPair(10, 2)
220  ->ArgPair(10, 4)
221  ->ArgPair(10, 8);
222 BENCHMARK_TEMPLATE(BM_SimpleAtof, const char*)
223  ->ArgPair(10, 1)
224  ->ArgPair(10, 2)
225  ->ArgPair(10, 4)
226  ->ArgPair(10, 8);
227 BENCHMARK_TEMPLATE(BM_SimpleAtof, std::string)
228  ->ArgPair(10, 1)
229  ->ArgPair(10, 2)
230  ->ArgPair(10, 4)
231  ->ArgPair(10, 8);
232 
233 template <typename T>
234 void BM_SimpleAtod(benchmark::State& state) {
235  const int num_strings = state.range(0);
236  const int num_digits = state.range(1);
237  std::vector<std::string> backing_strings =
238  MakeFloatStrings(num_strings, num_digits);
239  std::vector<T> inputs = GetStringsAs<T>(backing_strings);
240  double value;
241  for (auto _ : state) {
242  for (const T& input : inputs) {
243  benchmark::DoNotOptimize(absl::SimpleAtod(input, &value));
244  }
245  }
246 }
247 BENCHMARK_TEMPLATE(BM_SimpleAtod, absl::string_view)
248  ->ArgPair(10, 1)
249  ->ArgPair(10, 2)
250  ->ArgPair(10, 4)
251  ->ArgPair(10, 8);
252 BENCHMARK_TEMPLATE(BM_SimpleAtod, const char*)
253  ->ArgPair(10, 1)
254  ->ArgPair(10, 2)
255  ->ArgPair(10, 4)
256  ->ArgPair(10, 8);
257 BENCHMARK_TEMPLATE(BM_SimpleAtod, std::string)
258  ->ArgPair(10, 1)
259  ->ArgPair(10, 2)
260  ->ArgPair(10, 4)
261  ->ArgPair(10, 8);
262 
263 } // namespace
bool safe_strtou64_base(absl::string_view text, uint64_t *value, int base)
Definition: numbers.cc:900
char * FastIntToBuffer(int32_t, char *)
Definition: numbers.cc:241
char buf[N]
bool safe_strtou32_base(absl::string_view text, uint32_t *value, int base)
Definition: numbers.cc:896
bool SimpleAtod(absl::string_view str, double *out)
Definition: numbers.cc:69
bool SimpleAtof(absl::string_view str, float *out)
Definition: numbers.cc:43
bool safe_strto32_base(absl::string_view text, int32_t *value, int base)
Definition: numbers.cc:888
#define ABSL_RAW_CHECK(condition, message)
Definition: raw_logging.h:57
size_t value
bool safe_strto64_base(absl::string_view text, int64_t *value, int base)
Definition: numbers.cc:892
static const int kFastToBufferSize
Definition: numbers.h:93


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:19