[libcxx-commits] [PATCH] D101752: Speedup to_string for integers using zero-copy.
Roman Koshelev via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu May 6 22:12:36 PDT 2021
Roman-Koshelev added a comment.
Source
#include <algorithm>
#include <vector>
#include <charconv>
#include <random>
#include <benchmark/benchmark.h>
template <typename V>
std::string i_to_stringN(const V v)
{
std::string buf;
buf.resize(buf.capacity());
const auto res = std::to_chars(buf.data(), buf.data() + buf.size(), v);
buf.resize(res.ptr - buf.data());
return buf;
}
std::string to_stringN (int val) { return i_to_stringN(val); }
std::string to_stringN (long val) { return i_to_stringN(val); }
std::string to_stringN (long long val) { return i_to_stringN(val); }
std::string to_stringN (unsigned val) { return i_to_stringN(val); }
std::string to_stringN (unsigned long val) { return i_to_stringN(val); }
std::string to_stringN (unsigned long long val) { return i_to_stringN(val); }
template <typename V>
std::string i_to_stringO(const V v)
{
constexpr size_t bufsize = std::numeric_limits<V>::digits10 + 2;
char buf[bufsize];
const auto res = std::to_chars(buf, buf + bufsize, v);
return std::string(buf, res.ptr);
}
std::string to_stringO (int val) { return i_to_stringO(val); }
std::string to_stringO (long val) { return i_to_stringO(val); }
std::string to_stringO (long long val) { return i_to_stringO(val); }
std::string to_stringO (unsigned val) { return i_to_stringO(val); }
std::string to_stringO (unsigned long val) { return i_to_stringO(val); }
std::string to_stringO (unsigned long long val) { return i_to_stringO(val); }
template <unsigned N>
struct make_mem
{
using type = std::conditional_t<
N <= sizeof(std::uint8_t), std::uint8_t,
std::conditional_t<
N <= sizeof(std::uint16_t), std::uint16_t,
std::conditional_t<
N <= sizeof(std::uint32_t), std::uint32_t, std::uint64_t>>>;
};
template <unsigned N>
using make_mem_t = typename make_mem<N>::type;
std::random_device rd;
std::mt19937 gen(rd());
template<unsigned N, bool IsNew>
static void to_stringD(benchmark::State& state) {
using Ty = make_mem_t<N>;
std::uniform_int_distribution<Ty> distrib(std::numeric_limits<Ty>::min(), std::numeric_limits<Ty>::max());
std::vector<Ty> vec;
vec.reserve(128);
for(int i=0; i<128; ++i) {
vec.push_back(distrib(gen));
}
for (auto _ : state) {
for(Ty i : vec) {
if constexpr (IsNew) {
std::string res = to_stringN(i);
benchmark::DoNotOptimize(res);
} else {
std::string res = to_stringO(i);
benchmark::DoNotOptimize(res);
}
}
}
}
static void to_stringNewBench(benchmark::State& state) {
switch(state.range(0)) {
case 1: { to_stringD<1, true>(state); return; }
case 2: { to_stringD<2, true>(state); return; }
case 3: { to_stringD<3, true>(state); return; }
case 4: { to_stringD<4, true>(state); return; }
case 5: { to_stringD<5, true>(state); return; }
case 6: { to_stringD<6, true>(state); return; }
case 7: { to_stringD<7, true>(state); return; }
case 8: { to_stringD<8, true>(state); return; }
case 9: { to_stringD<9, true>(state); return; }
case 10: { to_stringD<10, true>(state); return; }
case 11: { to_stringD<11, true>(state); return; }
case 12: { to_stringD<12, true>(state); return; }
case 13: { to_stringD<13, true>(state); return; }
case 14: { to_stringD<14, true>(state); return; }
case 15: { to_stringD<15, true>(state); return; }
case 16: { to_stringD<16, true>(state); return; }
default: assert(false);
}
}
BENCHMARK(to_stringNewBench)->DenseRange(1, 16);
static void to_stringOldBench(benchmark::State& state) {
switch(state.range(0)) {
case 1: { to_stringD<1, false>(state); return; }
case 2: { to_stringD<2, false>(state); return; }
case 3: { to_stringD<3, false>(state); return; }
case 4: { to_stringD<4, false>(state); return; }
case 5: { to_stringD<5, false>(state); return; }
case 6: { to_stringD<6, false>(state); return; }
case 7: { to_stringD<7, false>(state); return; }
case 8: { to_stringD<8, false>(state); return; }
case 9: { to_stringD<9, false>(state); return; }
case 10: { to_stringD<10, false>(state); return; }
case 11: { to_stringD<11, false>(state); return; }
case 12: { to_stringD<12, false>(state); return; }
case 13: { to_stringD<13, false>(state); return; }
case 14: { to_stringD<14, false>(state); return; }
case 15: { to_stringD<15, false>(state); return; }
case 16: { to_stringD<16, false>(state); return; }
default: assert(false);
}
}
BENCHMARK(to_stringOldBench)->DenseRange(1, 16);
BENCHMARK_MAIN();
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D101752/new/
https://reviews.llvm.org/D101752
More information about the libcxx-commits
mailing list