From 3017fc6fb7f4e098533d3f377b2bb30ccaf44695 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 17 Feb 2014 09:12:24 -0800 Subject: [PATCH] Improve 32-bit integer formatting performance by parameterizing FormatDecimal on integer type. --- format.cc | 29 ----------------------------- format.h | 24 ++++++++++++++++++++++-- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/format.cc b/format.cc index 869046b0..c5473b59 100644 --- a/format.cc +++ b/format.cc @@ -169,29 +169,6 @@ typename fmt::BasicWriter::CharPtr return content; } -template -void fmt::internal::FormatDecimal( - Char *buffer, uint64_t value, unsigned num_digits) { - --num_digits; - while (value >= 100) { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = (value % 100) * 2; - value /= 100; - buffer[num_digits] = internal::DIGITS[index + 1]; - buffer[num_digits - 1] = internal::DIGITS[index]; - num_digits -= 2; - } - if (value < 10) { - *buffer = static_cast('0' + value); - return; - } - unsigned index = static_cast(value * 2); - buffer[1] = internal::DIGITS[index + 1]; - buffer[0] = internal::DIGITS[index]; -} - template typename fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( @@ -700,9 +677,6 @@ template fmt::BasicWriter::CharPtr fmt::BasicWriter::FillPadding(CharPtr buffer, unsigned total_size, std::size_t content_size, wchar_t fill); -template void fmt::internal::FormatDecimal( - char *buffer, uint64_t value, unsigned num_digits); - template fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( unsigned size, const AlignSpec &spec, char sign); @@ -732,9 +706,6 @@ template fmt::BasicWriter::CharPtr fmt::BasicWriter::FillPadding(CharPtr buffer, unsigned total_size, std::size_t content_size, wchar_t fill); -template void fmt::internal::FormatDecimal( - wchar_t *buffer, uint64_t value, unsigned num_digits); - template fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( unsigned size, const AlignSpec &spec, char sign); diff --git a/format.h b/format.h index d8241796..b24b2ad8 100644 --- a/format.h +++ b/format.h @@ -276,8 +276,28 @@ extern const char DIGITS[]; template class FormatterProxy; -template -void FormatDecimal(Char *buffer, uint64_t value, unsigned num_digits); +// Formats a decimal unsigned integer value writing into buffer. +template +void FormatDecimal(Char *buffer, UInt value, unsigned num_digits) { + --num_digits; + while (value >= 100) { + // Integer division is slow so do it for a group of two digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + unsigned index = (value % 100) * 2; + value /= 100; + buffer[num_digits] = internal::DIGITS[index + 1]; + buffer[num_digits - 1] = internal::DIGITS[index]; + num_digits -= 2; + } + if (value < 10) { + *buffer = static_cast('0' + value); + return; + } + unsigned index = static_cast(value * 2); + buffer[1] = internal::DIGITS[index + 1]; + buffer[0] = internal::DIGITS[index]; +} } /**