Skip to content

Commit 3017fc6

Browse files
committed
Improve 32-bit integer formatting performance by parameterizing FormatDecimal on integer type.
1 parent 6f6fe51 commit 3017fc6

File tree

2 files changed

+22
-31
lines changed

2 files changed

+22
-31
lines changed

format.cc

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -169,29 +169,6 @@ typename fmt::BasicWriter<Char>::CharPtr
169169
return content;
170170
}
171171

172-
template <typename Char>
173-
void fmt::internal::FormatDecimal(
174-
Char *buffer, uint64_t value, unsigned num_digits) {
175-
--num_digits;
176-
while (value >= 100) {
177-
// Integer division is slow so do it for a group of two digits instead
178-
// of for every digit. The idea comes from the talk by Alexandrescu
179-
// "Three Optimization Tips for C++". See speed-test for a comparison.
180-
unsigned index = (value % 100) * 2;
181-
value /= 100;
182-
buffer[num_digits] = internal::DIGITS[index + 1];
183-
buffer[num_digits - 1] = internal::DIGITS[index];
184-
num_digits -= 2;
185-
}
186-
if (value < 10) {
187-
*buffer = static_cast<char>('0' + value);
188-
return;
189-
}
190-
unsigned index = static_cast<unsigned>(value * 2);
191-
buffer[1] = internal::DIGITS[index + 1];
192-
buffer[0] = internal::DIGITS[index];
193-
}
194-
195172
template <typename Char>
196173
typename fmt::BasicWriter<Char>::CharPtr
197174
fmt::BasicWriter<Char>::PrepareFilledBuffer(
@@ -700,9 +677,6 @@ template fmt::BasicWriter<char>::CharPtr
700677
fmt::BasicWriter<char>::FillPadding(CharPtr buffer,
701678
unsigned total_size, std::size_t content_size, wchar_t fill);
702679

703-
template void fmt::internal::FormatDecimal<char>(
704-
char *buffer, uint64_t value, unsigned num_digits);
705-
706680
template fmt::BasicWriter<char>::CharPtr
707681
fmt::BasicWriter<char>::PrepareFilledBuffer(
708682
unsigned size, const AlignSpec &spec, char sign);
@@ -732,9 +706,6 @@ template fmt::BasicWriter<wchar_t>::CharPtr
732706
fmt::BasicWriter<wchar_t>::FillPadding(CharPtr buffer,
733707
unsigned total_size, std::size_t content_size, wchar_t fill);
734708

735-
template void fmt::internal::FormatDecimal<wchar_t>(
736-
wchar_t *buffer, uint64_t value, unsigned num_digits);
737-
738709
template fmt::BasicWriter<wchar_t>::CharPtr
739710
fmt::BasicWriter<wchar_t>::PrepareFilledBuffer(
740711
unsigned size, const AlignSpec &spec, char sign);

format.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,28 @@ extern const char DIGITS[];
276276
template <typename Char>
277277
class FormatterProxy;
278278

279-
template <typename Char>
280-
void FormatDecimal(Char *buffer, uint64_t value, unsigned num_digits);
279+
// Formats a decimal unsigned integer value writing into buffer.
280+
template <typename UInt, typename Char>
281+
void FormatDecimal(Char *buffer, UInt value, unsigned num_digits) {
282+
--num_digits;
283+
while (value >= 100) {
284+
// Integer division is slow so do it for a group of two digits instead
285+
// of for every digit. The idea comes from the talk by Alexandrescu
286+
// "Three Optimization Tips for C++". See speed-test for a comparison.
287+
unsigned index = (value % 100) * 2;
288+
value /= 100;
289+
buffer[num_digits] = internal::DIGITS[index + 1];
290+
buffer[num_digits - 1] = internal::DIGITS[index];
291+
num_digits -= 2;
292+
}
293+
if (value < 10) {
294+
*buffer = static_cast<char>('0' + value);
295+
return;
296+
}
297+
unsigned index = static_cast<unsigned>(value * 2);
298+
buffer[1] = internal::DIGITS[index + 1];
299+
buffer[0] = internal::DIGITS[index];
300+
}
281301
}
282302

283303
/**

0 commit comments

Comments
 (0)