Improve 32-bit integer formatting performance by parameterizing FormatDecimal on integer type.

This commit is contained in:
Victor Zverovich 2014-02-17 09:12:24 -08:00
parent 6f6fe519e2
commit 3017fc6fb7
2 changed files with 22 additions and 31 deletions

View File

@ -169,29 +169,6 @@ typename fmt::BasicWriter<Char>::CharPtr
return content;
}
template <typename Char>
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<char>('0' + value);
return;
}
unsigned index = static_cast<unsigned>(value * 2);
buffer[1] = internal::DIGITS[index + 1];
buffer[0] = internal::DIGITS[index];
}
template <typename Char>
typename fmt::BasicWriter<Char>::CharPtr
fmt::BasicWriter<Char>::PrepareFilledBuffer(
@ -700,9 +677,6 @@ template fmt::BasicWriter<char>::CharPtr
fmt::BasicWriter<char>::FillPadding(CharPtr buffer,
unsigned total_size, std::size_t content_size, wchar_t fill);
template void fmt::internal::FormatDecimal<char>(
char *buffer, uint64_t value, unsigned num_digits);
template fmt::BasicWriter<char>::CharPtr
fmt::BasicWriter<char>::PrepareFilledBuffer(
unsigned size, const AlignSpec &spec, char sign);
@ -732,9 +706,6 @@ template fmt::BasicWriter<wchar_t>::CharPtr
fmt::BasicWriter<wchar_t>::FillPadding(CharPtr buffer,
unsigned total_size, std::size_t content_size, wchar_t fill);
template void fmt::internal::FormatDecimal<wchar_t>(
wchar_t *buffer, uint64_t value, unsigned num_digits);
template fmt::BasicWriter<wchar_t>::CharPtr
fmt::BasicWriter<wchar_t>::PrepareFilledBuffer(
unsigned size, const AlignSpec &spec, char sign);

View File

@ -276,8 +276,28 @@ extern const char DIGITS[];
template <typename Char>
class FormatterProxy;
template <typename Char>
void FormatDecimal(Char *buffer, uint64_t value, unsigned num_digits);
// Formats a decimal unsigned integer value writing into buffer.
template <typename UInt, typename Char>
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<char>('0' + value);
return;
}
unsigned index = static_cast<unsigned>(value * 2);
buffer[1] = internal::DIGITS[index + 1];
buffer[0] = internal::DIGITS[index];
}
}
/**