aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-26 17:29:16 +0100
committereunhhu <[email protected]>2026-09-26 17:29:16 +0100
commit3d277c7714d7a8e2e0e7f9eb627722b83991effd (patch)
tree7d86063db5abf4dc73825141cb6188cdeb72fb9b
parent768317d789a01d722fe7455d792fed11e6579b5c (diff)
downloadpure-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.c12
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;