diff options
| author | eunhhu <[email protected]> | 2026-09-26 17:29:16 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-26 17:29:16 +0100 |
| commit | 3d277c7714d7a8e2e0e7f9eb627722b83991effd (patch) | |
| tree | 7d86063db5abf4dc73825141cb6188cdeb72fb9b | |
| parent | 768317d789a01d722fe7455d792fed11e6579b5c (diff) | |
| download | pure-3d277c7714d7a8e2e0e7f9eb627722b83991effd.tar.gz pure-3d277c7714d7a8e2e0e7f9eb627722b83991effd.zip | |
Format integers without printf
pure_format_number, behind every number a text shows (interpolation, the
views pure-serve answers, pure-run), printed integers with
snprintf("%.0f"): hundreds of nanoseconds each on the Pi, most of a page of
20 rows. Integers below 1e15 now take their digits directly (21 ns),
identical to printf on 2.6 million random integers.
| -rw-r--r-- | prototypes/connections/module-text.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/prototypes/connections/module-text.c b/prototypes/connections/module-text.c index 5c9efe1..596585c 100644 --- a/prototypes/connections/module-text.c +++ b/prototypes/connections/module-text.c @@ -56,7 +56,17 @@ size_t pure_utf8_newlines(PureSpan span) { size_t pure_format_number(double value, char out[32]) { if (value == 0) { memcpy(out, "0", 2); return 1; } - if (value == floor(value) && fabs(value) < 1e15) return (size_t)snprintf(out, 32, "%.0f", value); + if (value == floor(value) && fabs(value) < 1e15) { + /* An integer's digits, without printf (the common case, many times cheaper). */ + char digits[16]; + uint64_t n = (uint64_t)fabs(value); + size_t count = 0, length = 0; + do { digits[count++] = (char)('0' + n % 10); n /= 10; } while (n); + if (value < 0) out[length++] = '-'; + while (count) out[length++] = digits[--count]; + out[length] = 0; + return length; + } for (int precision = 1; precision <= 17; ++precision) { snprintf(out, 32, "%.*g", precision, value); if (strtod(out, NULL) == value) break; |
