diff options
author | Mattias Engdegård <mattiase@acm.org> | 2022-03-18 11:43:10 +0100 |
---|---|---|
committer | Mattias Engdegård <mattiase@acm.org> | 2022-03-18 11:54:08 +0100 |
commit | ce26657b5d7e77d851ed9267d554f4f48e43a0b6 (patch) | |
tree | 295a1e6bad8c60fb9408e6a2a408483959ec75c7 /src/data.c | |
parent | 2b05a06786e7b5adf9d4329959da49d9b40c2bef (diff) | |
download | emacs-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.c | 28 |
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, |