diff --git a/poc/int_to_string/benchmark.cpp b/poc/int_to_string/benchmark.cpp index bb5dbdf..9540468 100644 --- a/poc/int_to_string/benchmark.cpp +++ b/poc/int_to_string/benchmark.cpp @@ -46,13 +46,13 @@ int main() result_buffer_type buffer = {}; uint64_t integer = std::numeric_limits::max(); - auto start = std::chrono::system_clock::now(); + auto start = std::chrono::steady_clock::now(); for (size_t i = 0; i < loop_count; ++i) { _ui64toa(integer, buffer.data(), 10); integer -= reduction_value; } - auto end = std::chrono::system_clock::now(); + auto end = std::chrono::steady_clock::now(); auto elapsed = end - start; std::cout << std::chrono::duration_cast(elapsed).count() << " ms\n"; } @@ -63,14 +63,15 @@ int main() uint64_t integer = std::numeric_limits::max(); uint64_t accumulated_characters = 0; - auto start = std::chrono::system_clock::now(); + auto start = std::chrono::steady_clock::now(); + for (size_t i = 0; i < loop_count; ++i) { auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), integer); accumulated_characters += static_cast(ptr - buffer.data()); integer -= reduction_value; } - auto end = std::chrono::system_clock::now(); + auto end = std::chrono::steady_clock::now(); auto elapsed = end - start; std::cout << std::chrono::duration_cast(elapsed).count() << " ms "; @@ -85,13 +86,13 @@ int main() uint64_t integer = std::numeric_limits::max(); uint64_t accumulated_characters = 0; - auto start = std::chrono::system_clock::now(); + auto start = std::chrono::steady_clock::now(); for (size_t i = 0; i < loop_count; ++i) { accumulated_characters += int_to_string(integer, buffer); integer -= reduction_value; } - auto end = std::chrono::system_clock::now(); + auto end = std::chrono::steady_clock::now(); auto elapsed = end - start; diff --git a/poc/int_to_string/int_to_string.h b/poc/int_to_string/int_to_string.h index 8e4a32f..7a613e0 100644 --- a/poc/int_to_string/int_to_string.h +++ b/poc/int_to_string/int_to_string.h @@ -181,19 +181,19 @@ constexpr std::uint8_t int_to_string(T integer_value, result_buffer_type &target // digit count via logarithm lookup std::uint8_t digits_left_to_encode = detail::digit_count(number_to_encode); - static_assert(std::clamp(static_cast(201), static_cast(0U), static_cast(199U)) == - 199); - - // left-to-right extraction, 2 digits (0-99) per loop - // Each iteration costs: 1 divide + 1 multiply + 1 subtract - // (vs. 2 divides + 2 mods in the classic right-to-left scheme) - while (digits_left_to_encode >= 2) +// left-to-right extraction, 2 digits (0-99) per loop +// Each iteration costs: 1 divide + 1 multiply + 1 subtract +// (vs. 2 divides + 2 mods in the classic right-to-left scheme) +#if KDTOOLBOX_ASTREE + __ASTREE_unroll((20)) +#endif + while (digits_left_to_encode >= 2) { std::uint64_t divisor = detail::pow10[digits_left_to_encode - 2]; // 10^(L-2) - auto chunk = static_cast((number_to_encode / divisor) & 0xFFFFULL); + auto chunk = static_cast(number_to_encode / divisor); // chunk must be possible to multiply by 2 without overflow - std::uint8_t lut_index = (chunk & static_cast(0b01111111)) * 2; + std::uint8_t lut_index = chunk * 2; lut_index = std::clamp(lut_index, static_cast(0U), static_cast(detail::two_digit_lut.size() - 1)); diff --git a/poc/int_to_string/main.cpp b/poc/int_to_string/main.cpp index 4a8e70f..d6116e1 100644 --- a/poc/int_to_string/main.cpp +++ b/poc/int_to_string/main.cpp @@ -13,7 +13,10 @@ This file is part of KDToolBox. constexpr bool compare_number(result_buffer_type &source, size_t num_characters, const std::string &expected) { - for (size_t i = 0; i < num_characters; i++) +#if KDTOOLBOX_ASTREE + __ASTREE_unroll((20)) +#endif + for (size_t i = 0; i < num_characters; i++) { if (source[i] != expected[i]) return false;