summaryrefslogtreecommitdiff
path: root/src/data.c
diff options
context:
space:
mode:
authorMattias Engdegård <mattiase@acm.org>2022-03-18 11:43:10 +0100
committerMattias Engdegård <mattiase@acm.org>2022-03-18 11:54:08 +0100
commitce26657b5d7e77d851ed9267d554f4f48e43a0b6 (patch)
tree295a1e6bad8c60fb9408e6a2a408483959ec75c7 /src/data.c
parent2b05a06786e7b5adf9d4329959da49d9b40c2bef (diff)
downloademacs-ce26657b5d7e77d851ed9267d554f4f48e43a0b6.tar.gz
Speed up number-to-string for fixnums
Do the binary-to-decimal conversion by hand for fixnums instead of calling sprintf. This results in a noticeable speed increase (on my machine, 2.2× faster excluding GC). * src/data.c (Fnumber_to_string): Don't use sprintf for fixnums.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/data.c b/src/data.c
index 1526cc0c737..6eda0089702 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2975,19 +2975,35 @@ NUMBER may be an integer or a floating point number. */)
(Lisp_Object number)
{
char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))];
- int len;
- CHECK_NUMBER (number);
+ if (FIXNUMP (number))
+ {
+ EMACS_INT x = XFIXNUM (number);
+ bool negative = x < 0;
+ if (negative)
+ x = -x;
+ char *end = buffer + sizeof buffer;
+ char *p = end;
+ do
+ {
+ eassume (p > buffer && p - 1 < buffer + sizeof buffer);
+ *--p = '0' + x % 10;
+ x /= 10;
+ }
+ while (x);
+ if (negative)
+ *--p = '-';
+ return make_unibyte_string (p, end - p);
+ }
if (BIGNUMP (number))
return bignum_to_string (number, 10);
if (FLOATP (number))
- len = float_to_string (buffer, XFLOAT_DATA (number));
- else
- len = sprintf (buffer, "%"pI"d", XFIXNUM (number));
+ return make_unibyte_string (buffer,
+ float_to_string (buffer, XFLOAT_DATA (number)));
- return make_unibyte_string (buffer, len);
+ wrong_type_argument (Qnumberp, number);
}
DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0,