blob: bde75250767950923d1216564d071dfa3ada7ce6 [file] [edit]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Benchmarks for string to floating point conversion.
///
//===----------------------------------------------------------------------===//
#include "benchmark/benchmark.h"
#include "src/__support/str_to_float.h"
#include <stddef.h>
#include <stdint.h>
namespace {
// Normals.
constexpr const char *NORMAL_SHORT[] = {
"0", "1", "1.5", "-3.75", "0.1", "12.5", "3.14159", "100", "1e10", "1e-10",
};
// Normals with enough digits or exponent to reach the fallback.
constexpr const char *NORMAL_LONG[] = {
"1.00000000000000000001", "0.99999999999999999999",
"123456789012345678901234567890", "1.7976931348623157e308",
"2.2250738585072014e-308",
};
// Subnormals.
constexpr const char *SUBNORMAL_SHORT[] = {
"5e-324", "1e-320", "2.5e-320", "1e-315", "3.33e-318", "7e-309",
};
// Subnormals with many digits.
constexpr const char *SUBNORMAL_LONG[] = {
"4.940656458412465441765687928682213723651e-324",
"1.797693134862315708145274237317043567981e-320",
};
// Subnormal as a float; the doubles above underflow to zero here.
constexpr const char *FLOAT_SUBNORMAL[] = {
"1e-38", "5e-39", "1e-40", "1e-42", "1e-44", "1.4012984643e-45",
};
template <typename T, size_t N>
void run(benchmark::State &state, const char *const (&inputs)[N]) {
for (auto _ : state) {
for (const char *input : inputs)
benchmark::DoNotOptimize(
LIBC_NAMESPACE::internal::strtofloatingpoint<T>(input));
}
state.SetItemsProcessed(state.iterations() * N);
}
void BM_StrToDoubleNormalShort(benchmark::State &state) {
run<double>(state, NORMAL_SHORT);
}
void BM_StrToDoubleNormalLong(benchmark::State &state) {
run<double>(state, NORMAL_LONG);
}
void BM_StrToDoubleSubnormalShort(benchmark::State &state) {
run<double>(state, SUBNORMAL_SHORT);
}
void BM_StrToDoubleSubnormalLong(benchmark::State &state) {
run<double>(state, SUBNORMAL_LONG);
}
void BM_StrToFloatNormalShort(benchmark::State &state) {
run<float>(state, NORMAL_SHORT);
}
void BM_StrToFloatSubnormalShort(benchmark::State &state) {
run<float>(state, SUBNORMAL_SHORT);
}
void BM_StrToFloatSubnormal(benchmark::State &state) {
run<float>(state, FLOAT_SUBNORMAL);
}
} // namespace
BENCHMARK(BM_StrToDoubleNormalShort);
BENCHMARK(BM_StrToDoubleNormalLong);
BENCHMARK(BM_StrToDoubleSubnormalShort);
BENCHMARK(BM_StrToDoubleSubnormalLong);
BENCHMARK(BM_StrToFloatNormalShort);
BENCHMARK(BM_StrToFloatSubnormalShort);
BENCHMARK(BM_StrToFloatSubnormal);