mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Improve printf("%d") speed.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
*>
|
||||
|
||||
Reference in New Issue
Block a user