00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <cstdint>
00016 #include <random>
00017 #include <string>
00018 #include <type_traits>
00019 #include <vector>
00020
00021 #include "benchmark/benchmark.h"
00022 #include "absl/base/internal/raw_logging.h"
00023 #include "absl/strings/numbers.h"
00024
00025 namespace {
00026
00027 template <typename T>
00028 void BM_FastIntToBuffer(benchmark::State& state) {
00029 const int inc = state.range(0);
00030 char buf[absl::numbers_internal::kFastToBufferSize];
00031
00032
00033 typename std::make_unsigned<T>::type x = 0;
00034 for (auto _ : state) {
00035 absl::numbers_internal::FastIntToBuffer(static_cast<T>(x), buf);
00036 x += inc;
00037 }
00038 }
00039 BENCHMARK_TEMPLATE(BM_FastIntToBuffer, int32_t)->Range(0, 1 << 15);
00040 BENCHMARK_TEMPLATE(BM_FastIntToBuffer, int64_t)->Range(0, 1 << 30);
00041
00042
00043
00044 int64_t RepeatedSevens(int num_digits, int base) {
00045 ABSL_RAW_CHECK(base >= 8, "");
00046 int64_t num = 7;
00047 while (--num_digits) num = base * num + 7;
00048 return num;
00049 }
00050
00051 void BM_safe_strto32_string(benchmark::State& state) {
00052 const int digits = state.range(0);
00053 const int base = state.range(1);
00054 std::string str(digits, '7');
00055 int32_t value = 0;
00056 for (auto _ : state) {
00057 benchmark::DoNotOptimize(
00058 absl::numbers_internal::safe_strto32_base(str, &value, base));
00059 }
00060 ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
00061 }
00062 BENCHMARK(BM_safe_strto32_string)
00063 ->ArgPair(1, 8)
00064 ->ArgPair(1, 10)
00065 ->ArgPair(1, 16)
00066 ->ArgPair(2, 8)
00067 ->ArgPair(2, 10)
00068 ->ArgPair(2, 16)
00069 ->ArgPair(4, 8)
00070 ->ArgPair(4, 10)
00071 ->ArgPair(4, 16)
00072 ->ArgPair(8, 8)
00073 ->ArgPair(8, 10)
00074 ->ArgPair(8, 16)
00075 ->ArgPair(10, 8)
00076 ->ArgPair(9, 10);
00077
00078 void BM_safe_strto64_string(benchmark::State& state) {
00079 const int digits = state.range(0);
00080 const int base = state.range(1);
00081 std::string str(digits, '7');
00082 int64_t value = 0;
00083 for (auto _ : state) {
00084 benchmark::DoNotOptimize(
00085 absl::numbers_internal::safe_strto64_base(str, &value, base));
00086 }
00087 ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
00088 }
00089 BENCHMARK(BM_safe_strto64_string)
00090 ->ArgPair(1, 8)
00091 ->ArgPair(1, 10)
00092 ->ArgPair(1, 16)
00093 ->ArgPair(2, 8)
00094 ->ArgPair(2, 10)
00095 ->ArgPair(2, 16)
00096 ->ArgPair(4, 8)
00097 ->ArgPair(4, 10)
00098 ->ArgPair(4, 16)
00099 ->ArgPair(8, 8)
00100 ->ArgPair(8, 10)
00101 ->ArgPair(8, 16)
00102 ->ArgPair(16, 8)
00103 ->ArgPair(16, 10)
00104 ->ArgPair(16, 16);
00105
00106 void BM_safe_strtou32_string(benchmark::State& state) {
00107 const int digits = state.range(0);
00108 const int base = state.range(1);
00109 std::string str(digits, '7');
00110 uint32_t value = 0;
00111 for (auto _ : state) {
00112 benchmark::DoNotOptimize(
00113 absl::numbers_internal::safe_strtou32_base(str, &value, base));
00114 }
00115 ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
00116 }
00117 BENCHMARK(BM_safe_strtou32_string)
00118 ->ArgPair(1, 8)
00119 ->ArgPair(1, 10)
00120 ->ArgPair(1, 16)
00121 ->ArgPair(2, 8)
00122 ->ArgPair(2, 10)
00123 ->ArgPair(2, 16)
00124 ->ArgPair(4, 8)
00125 ->ArgPair(4, 10)
00126 ->ArgPair(4, 16)
00127 ->ArgPair(8, 8)
00128 ->ArgPair(8, 10)
00129 ->ArgPair(8, 16)
00130 ->ArgPair(10, 8)
00131 ->ArgPair(9, 10);
00132
00133 void BM_safe_strtou64_string(benchmark::State& state) {
00134 const int digits = state.range(0);
00135 const int base = state.range(1);
00136 std::string str(digits, '7');
00137 uint64_t value = 0;
00138 for (auto _ : state) {
00139 benchmark::DoNotOptimize(
00140 absl::numbers_internal::safe_strtou64_base(str, &value, base));
00141 }
00142 ABSL_RAW_CHECK(value == RepeatedSevens(digits, base), "");
00143 }
00144 BENCHMARK(BM_safe_strtou64_string)
00145 ->ArgPair(1, 8)
00146 ->ArgPair(1, 10)
00147 ->ArgPair(1, 16)
00148 ->ArgPair(2, 8)
00149 ->ArgPair(2, 10)
00150 ->ArgPair(2, 16)
00151 ->ArgPair(4, 8)
00152 ->ArgPair(4, 10)
00153 ->ArgPair(4, 16)
00154 ->ArgPair(8, 8)
00155 ->ArgPair(8, 10)
00156 ->ArgPair(8, 16)
00157 ->ArgPair(16, 8)
00158 ->ArgPair(16, 10)
00159 ->ArgPair(16, 16);
00160
00161
00162
00163
00164 std::vector<std::string> MakeFloatStrings(int num_strings, int num_digits) {
00165
00166
00167 std::minstd_rand0 rng(1);
00168 std::uniform_int_distribution<int> random_digit('0', '9');
00169
00170 std::vector<std::string> float_strings(num_strings);
00171 for (std::string& s : float_strings) {
00172 s.reserve(2 * num_digits + 1);
00173 for (int i = 0; i < num_digits; ++i) {
00174 s.push_back(static_cast<char>(random_digit(rng)));
00175 }
00176 s.push_back('.');
00177 for (int i = 0; i < num_digits; ++i) {
00178 s.push_back(static_cast<char>(random_digit(rng)));
00179 }
00180 }
00181 return float_strings;
00182 }
00183
00184 template <typename StringType>
00185 StringType GetStringAs(const std::string& s) {
00186 return static_cast<StringType>(s);
00187 }
00188 template <>
00189 const char* GetStringAs<const char*>(const std::string& s) {
00190 return s.c_str();
00191 }
00192
00193 template <typename StringType>
00194 std::vector<StringType> GetStringsAs(const std::vector<std::string>& strings) {
00195 std::vector<StringType> result;
00196 result.reserve(strings.size());
00197 for (const std::string& s : strings) {
00198 result.push_back(GetStringAs<StringType>(s));
00199 }
00200 return result;
00201 }
00202
00203 template <typename T>
00204 void BM_SimpleAtof(benchmark::State& state) {
00205 const int num_strings = state.range(0);
00206 const int num_digits = state.range(1);
00207 std::vector<std::string> backing_strings =
00208 MakeFloatStrings(num_strings, num_digits);
00209 std::vector<T> inputs = GetStringsAs<T>(backing_strings);
00210 float value;
00211 for (auto _ : state) {
00212 for (const T& input : inputs) {
00213 benchmark::DoNotOptimize(absl::SimpleAtof(input, &value));
00214 }
00215 }
00216 }
00217 BENCHMARK_TEMPLATE(BM_SimpleAtof, absl::string_view)
00218 ->ArgPair(10, 1)
00219 ->ArgPair(10, 2)
00220 ->ArgPair(10, 4)
00221 ->ArgPair(10, 8);
00222 BENCHMARK_TEMPLATE(BM_SimpleAtof, const char*)
00223 ->ArgPair(10, 1)
00224 ->ArgPair(10, 2)
00225 ->ArgPair(10, 4)
00226 ->ArgPair(10, 8);
00227 BENCHMARK_TEMPLATE(BM_SimpleAtof, std::string)
00228 ->ArgPair(10, 1)
00229 ->ArgPair(10, 2)
00230 ->ArgPair(10, 4)
00231 ->ArgPair(10, 8);
00232
00233 template <typename T>
00234 void BM_SimpleAtod(benchmark::State& state) {
00235 const int num_strings = state.range(0);
00236 const int num_digits = state.range(1);
00237 std::vector<std::string> backing_strings =
00238 MakeFloatStrings(num_strings, num_digits);
00239 std::vector<T> inputs = GetStringsAs<T>(backing_strings);
00240 double value;
00241 for (auto _ : state) {
00242 for (const T& input : inputs) {
00243 benchmark::DoNotOptimize(absl::SimpleAtod(input, &value));
00244 }
00245 }
00246 }
00247 BENCHMARK_TEMPLATE(BM_SimpleAtod, absl::string_view)
00248 ->ArgPair(10, 1)
00249 ->ArgPair(10, 2)
00250 ->ArgPair(10, 4)
00251 ->ArgPair(10, 8);
00252 BENCHMARK_TEMPLATE(BM_SimpleAtod, const char*)
00253 ->ArgPair(10, 1)
00254 ->ArgPair(10, 2)
00255 ->ArgPair(10, 4)
00256 ->ArgPair(10, 8);
00257 BENCHMARK_TEMPLATE(BM_SimpleAtod, std::string)
00258 ->ArgPair(10, 1)
00259 ->ArgPair(10, 2)
00260 ->ArgPair(10, 4)
00261 ->ArgPair(10, 8);
00262
00263 }