Trying with a smaller lookup, still slower than std::to_string
This commit is contained in:
parent
9dbabcb5c4
commit
e3140a3add
2 changed files with 72 additions and 14 deletions
|
@ -159,14 +159,13 @@ namespace dhandy {
|
||||||
using RetType = RevArray<I, 10, Tr>;
|
using RetType = RevArray<I, 10, Tr>;
|
||||||
using Num = implem::NumberAdaptation<I, 10>;
|
using Num = implem::NumberAdaptation<I, 10>;
|
||||||
|
|
||||||
const constexpr char lookup[200] = {
|
//How to build this lookup: 1) write numbers 0, 10, 20..., 90
|
||||||
0,0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,1,0,1,1,1,2,1,3,1,4,
|
//in binary; 2) take the lowest 5 bits, div by 2 and write as
|
||||||
1,5,1,6,1,7,1,8,1,9,2,0,2,1,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,
|
//decimal; 3) divide by 2; 4) the result is the position in the
|
||||||
3,0,3,1,3,2,3,3,3,4,3,5,3,6,3,7,3,8,3,9,4,0,4,1,4,2,4,3,4,4,
|
//below array that should be filled in with the leading digit
|
||||||
4,5,4,6,4,7,4,8,4,9,5,0,5,1,5,2,5,3,5,4,5,5,5,6,5,7,5,8,5,9,
|
//from the original 0-90 number
|
||||||
6,0,6,1,6,2,6,3,6,4,6,5,6,6,6,7,6,8,6,9,7,0,7,1,7,2,7,3,7,4,
|
constexpr const char lookup[16] = {
|
||||||
7,5,7,6,7,7,7,8,7,9,8,0,8,1,8,2,8,3,8,4,8,5,8,6,8,7,8,8,8,9,
|
0, 0, 0, 7, 4, 1, 0, 0, 8, 5, 2, 0, 0, 9, 6, 3
|
||||||
9,0,9,1,9,2,9,3,9,4,9,5,9,6,9,7,9,8,9,9
|
|
||||||
};
|
};
|
||||||
const bool was_negative = implem::is_negative<I, 10>(in);
|
const bool was_negative = implem::is_negative<I, 10>(in);
|
||||||
|
|
||||||
|
@ -176,18 +175,21 @@ namespace dhandy {
|
||||||
arr.push_front(Tr::NullChar);
|
arr.push_front(Tr::NullChar);
|
||||||
in = Num::abs(in);
|
in = Num::abs(in);
|
||||||
while (in >= static_cast<I>(100)) {
|
while (in >= static_cast<I>(100)) {
|
||||||
const auto index = (in % 100) * 2;
|
const auto last_two = in % 100;
|
||||||
arr.push_front(Tr::to_digit(static_cast<int>(lookup[index + 1])));
|
const auto digit_low = in % 10;
|
||||||
arr.push_front(Tr::to_digit(static_cast<int>(lookup[index + 0])));
|
|
||||||
in = static_cast<I>(in / static_cast<I>(100));
|
in = static_cast<I>(in / static_cast<I>(100));
|
||||||
|
const auto digit_high = lookup[((last_two - digit_low) >> 1) & 0xF];
|
||||||
|
arr.push_front(Tr::to_digit(static_cast<int>(digit_low)));
|
||||||
|
arr.push_front(Tr::to_digit(static_cast<int>(digit_high)));
|
||||||
};
|
};
|
||||||
if (in < static_cast<I>(10)) {
|
if (in < static_cast<I>(10)) {
|
||||||
arr.push_front(Tr::to_digit(static_cast<int>(in)));
|
arr.push_front(Tr::to_digit(static_cast<int>(in)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const auto index = in * 2;
|
const auto digit_low = in % 10;
|
||||||
arr.push_front(Tr::to_digit(static_cast<int>(lookup[index + 1])));
|
const auto digit_high = lookup[((in - digit_low) >> 1) & 0xF];
|
||||||
arr.push_front(Tr::to_digit(static_cast<int>(lookup[index + 0])));
|
arr.push_front(Tr::to_digit(static_cast<int>(digit_low)));
|
||||||
|
arr.push_front(Tr::to_digit(static_cast<int>(digit_high)));
|
||||||
}
|
}
|
||||||
if (was_negative)
|
if (was_negative)
|
||||||
arr.push_front(Tr::Minus);
|
arr.push_front(Tr::Minus);
|
||||||
|
|
56
speed_test_int_conv.cpp
Normal file
56
speed_test_int_conv.cpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#include "duckhandy/int_conv.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
#include <chrono>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename Conv>
|
||||||
|
void run_with_timing (
|
||||||
|
const std::string& test_name,
|
||||||
|
const std::vector<unsigned int>& src,
|
||||||
|
std::vector<std::string>& dst,
|
||||||
|
Conv&& conv_func
|
||||||
|
) {
|
||||||
|
dst.clear();
|
||||||
|
dst.resize(src.size());
|
||||||
|
std::cout << test_name << "...\n";
|
||||||
|
const std::size_t count = src.size();
|
||||||
|
|
||||||
|
const auto t0 = std::chrono::high_resolution_clock::now();
|
||||||
|
for (std::size_t z = 0; z < count; ++z) {
|
||||||
|
dst[z] = conv_func(src[z]);
|
||||||
|
}
|
||||||
|
const auto t1 = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
std::chrono::duration<double> duration = t1 - t0;
|
||||||
|
std::cout << count << " conversions completed in " << duration.count() << " seconds\n";
|
||||||
|
}
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
using dhandy::int_conv;
|
||||||
|
constexpr const std::size_t count = 50'000'000;
|
||||||
|
|
||||||
|
std::vector<unsigned int> nums;
|
||||||
|
std::vector<std::string> strings;
|
||||||
|
std::mt19937 gen;
|
||||||
|
|
||||||
|
std::cout << "Setting up data...\n";
|
||||||
|
|
||||||
|
nums.resize(count);
|
||||||
|
strings.reserve(count);
|
||||||
|
gen.seed(std::time(nullptr));
|
||||||
|
|
||||||
|
std::cout << "Generating " << count << " random values...\n";
|
||||||
|
std::generate(nums.begin(), nums.end(), gen);
|
||||||
|
|
||||||
|
run_with_timing("Conversions with std::to_string", nums, strings, [](unsigned int n) { return std::to_string(n); });
|
||||||
|
run_with_timing("AryConversion with dhandy::int_conv", nums, strings, [](unsigned int n) { return int_conv<std::string>(n); });
|
||||||
|
|
||||||
|
std::cout << "All done, bye!\n";
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue