Improve printf("%d") speed.

This commit is contained in:
Christoffer Lerno
2025-11-28 17:04:04 +01:00
parent 2df51bfe07
commit 0a0e097bdf
2 changed files with 64 additions and 14 deletions

View File

@@ -526,6 +526,19 @@ fn usz? Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
return len;
}
const char[201] DIGIT_PAIRS @private =
"00102030405060708090"
"01112131415161718191"
"02122232425262728292"
"03132333435363738393"
"04142434445464748494"
"05152535455565758595"
"06162636465666768696"
"07172737475767778797"
"08182838485868788898"
"09192939495969798999";
fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
{
char[PRINTF_NTOA_BUFFER_SIZE] buf @noinit;
@@ -538,14 +551,56 @@ fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
if (!self.flags.precision || value)
{
char past_10 = (self.flags.uppercase ? 'A' : 'a') - 10;
do
switch (base)
{
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
char digit = (char)(value % base);
buf[len++] = digit + (digit < 10 ? '0' : past_10);
value /= base;
case 2:
do
{
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
buf[len++] = '0' + (char)value & 1;
value >>= 1;
}
while (value);
case 10:
if (!value)
{
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
buf[len++] = '0';
break;
}
while (value >= 10)
{
if (len + 1 >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
char digit = (char)(value % 100);
buf[len:2] = DIGIT_PAIRS[2 * digit:2];
len += 2;
value /= 100;
}
if (value > 0)
{
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
buf[len++] = '0' + (char)value;
}
case 16:
do
{
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
char digit = (char)value & 0xF;
buf[len++] = digit + (digit < 10 ? '0' : past_10);
value >>= 4;
}
while (value);
case 8:
do
{
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?;
buf[len++] = '0' + (char)value & 0x7;
value >>= 3;
}
while (value);
default:
unreachable();
}
while (value);
}
return self.ntoa_format((String)buf[:PRINTF_NTOA_BUFFER_SIZE], len, negative, base);
}

View File

@@ -522,16 +522,16 @@ fn usz? BigInt.to_format(&self, Formatter* format) @dynamic
len++;
a.negate();
}
uint[280] chunks;
uint[280] chunks @noinit;
int chunk_count;
const BASE10_9 = 1000000000;
foreach_r(d : self.data)
foreach_r(d : self.data[:self.len])
{
ulong carry = d;
for (int i = 0; i < chunk_count; i++)
{
ulong v = chunks[i] * 4294967296ULL + carry;
ulong v = (ulong)chunks[i] << 32 + carry;
carry = v / BASE10_9;
chunks[i] = (uint)(v - carry * BASE10_9);
}
@@ -551,11 +551,6 @@ fn usz? BigInt.to_format(&self, Formatter* format) @dynamic
return len;
}
fn String BigInt.to_string(&self, Allocator allocator) @dynamic
{
return self.to_string_with_radix(10, allocator);
}
<*
@require radix > 1 && radix <= 36 : "Radix must be 2-36"
*>