From 8392b35d5062eb4b62b3041fbb01f58885155d0d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 9 Feb 2023 04:39:12 +0100 Subject: [PATCH] Speed up countDigits --- base/base/itoa.h | 68 ++++++++++++++++++----------------- src/Functions/countDigits.cpp | 59 +++++++++--------------------- 2 files changed, 51 insertions(+), 76 deletions(-) diff --git a/base/base/itoa.h b/base/base/itoa.h index dd3e3cc96fe..513070c99d9 100644 --- a/base/base/itoa.h +++ b/base/base/itoa.h @@ -33,6 +33,41 @@ #include +template +inline int digits10(T x) +{ + if (x < 10ULL) + return 1; + if (x < 100ULL) + return 2; + if (x < 1000ULL) + return 3; + + if (x < 1000000000000ULL) + { + if (x < 100000000ULL) + { + if (x < 1000000ULL) + { + if (x < 10000ULL) + return 4; + else + return 5 + (x >= 100000ULL); + } + + return 7 + (x >= 10000000ULL); + } + + if (x < 10000000000ULL) + return 9 + (x >= 1000000000ULL); + + return 11 + (x >= 100000000000ULL); + } + + return 12 + digits10(x / 1000000000000ULL); +} + + namespace impl { @@ -312,39 +347,6 @@ namespace convert } } -template -static inline int digits10(T x) -{ - if (x < 10ULL) - return 1; - if (x < 100ULL) - return 2; - if (x < 1000ULL) - return 3; - - if (x < 1000000000000ULL) - { - if (x < 100000000ULL) - { - if (x < 1000000ULL) - { - if (x < 10000ULL) - return 4; - else - return 5 + (x >= 100000ULL); - } - - return 7 + (x >= 10000000ULL); - } - - if (x < 10000000000ULL) - return 9 + (x >= 1000000000ULL); - - return 11 + (x >= 100000000000ULL); - } - - return 12 + digits10(x / 1000000000000ULL); -} template static inline char * writeUIntText(T x, char * p) diff --git a/src/Functions/countDigits.cpp b/src/Functions/countDigits.cpp index aefe0d92d94..2ca8d944b0a 100644 --- a/src/Functions/countDigits.cpp +++ b/src/Functions/countDigits.cpp @@ -2,9 +2,10 @@ #include #include #include -#include #include #include +#include +#include namespace DB @@ -83,7 +84,7 @@ private: template static void execute(const ColVecType & col, ColumnUInt8 & result_column, size_t rows_count) { - using NativeT = NativeType; + using NativeT = make_unsigned_t>; const auto & src_data = col.getData(); auto & dst_data = result_column.getData(); @@ -92,50 +93,22 @@ private: for (size_t i = 0; i < rows_count; ++i) { if constexpr (is_decimal) - dst_data[i] = digits(src_data[i].value); - else - dst_data[i] = digits(src_data[i]); - } - } - - template - static UInt32 digits(T value) - { - static_assert(!is_decimal); - using DivT = std::conditional_t, Int32, UInt32>; - - UInt32 res = 0; - T tmp; - - if constexpr (sizeof(T) > sizeof(Int32)) - { - static constexpr const DivT e9 = 1000000000; - - tmp = value / e9; - while (tmp != 0) { - value = tmp; - tmp /= e9; - res += 9; + auto value = src_data[i].value; + if (unlikely(value < 0)) + dst_data[i] = digits10(-static_cast(value)); + else + dst_data[i] = digits10(value); + } + else + { + auto value = src_data[i]; + if (unlikely(value < 0)) + dst_data[i] = digits10(-static_cast(value)); + else + dst_data[i] = digits10(value); } } - - static constexpr const DivT e3 = 1000; - - tmp = value / e3; - while (tmp != 0) - { - value = tmp; - tmp /= e3; - res += 3; - } - - while (value != 0) - { - value /= 10; - ++res; - } - return res; } };