diff options
| author | Mattias Engdegård | 2022-03-18 11:43:10 +0100 |
|---|---|---|
| committer | Mattias Engdegård | 2022-03-18 11:54:08 +0100 |
| commit | ce26657b5d7e77d851ed9267d554f4f48e43a0b6 (patch) | |
| tree | 295a1e6bad8c60fb9408e6a2a408483959ec75c7 /src/data.c | |
| parent | 2b05a06786e7b5adf9d4329959da49d9b40c2bef (diff) | |
| download | emacs-ce26657b5d7e77d851ed9267d554f4f48e43a0b6.tar.gz emacs-ce26657b5d7e77d851ed9267d554f4f48e43a0b6.zip | |
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. */) | |||
| 2975 | (Lisp_Object number) | 2975 | (Lisp_Object number) |
| 2976 | { | 2976 | { |
| 2977 | char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; | 2977 | char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; |
| 2978 | int len; | ||
| 2979 | 2978 | ||
| 2980 | CHECK_NUMBER (number); | 2979 | if (FIXNUMP (number)) |
| 2980 | { | ||
| 2981 | EMACS_INT x = XFIXNUM (number); | ||
| 2982 | bool negative = x < 0; | ||
| 2983 | if (negative) | ||
| 2984 | x = -x; | ||
| 2985 | char *end = buffer + sizeof buffer; | ||
| 2986 | char *p = end; | ||
| 2987 | do | ||
| 2988 | { | ||
| 2989 | eassume (p > buffer && p - 1 < buffer + sizeof buffer); | ||
| 2990 | *--p = '0' + x % 10; | ||
| 2991 | x /= 10; | ||
| 2992 | } | ||
| 2993 | while (x); | ||
| 2994 | if (negative) | ||
| 2995 | *--p = '-'; | ||
| 2996 | return make_unibyte_string (p, end - p); | ||
| 2997 | } | ||
| 2981 | 2998 | ||
| 2982 | if (BIGNUMP (number)) | 2999 | if (BIGNUMP (number)) |
| 2983 | return bignum_to_string (number, 10); | 3000 | return bignum_to_string (number, 10); |
| 2984 | 3001 | ||
| 2985 | if (FLOATP (number)) | 3002 | if (FLOATP (number)) |
| 2986 | len = float_to_string (buffer, XFLOAT_DATA (number)); | 3003 | return make_unibyte_string (buffer, |
| 2987 | else | 3004 | float_to_string (buffer, XFLOAT_DATA (number))); |
| 2988 | len = sprintf (buffer, "%"pI"d", XFIXNUM (number)); | ||
| 2989 | 3005 | ||
| 2990 | return make_unibyte_string (buffer, len); | 3006 | wrong_type_argument (Qnumberp, number); |
| 2991 | } | 3007 | } |
| 2992 | 3008 | ||
| 2993 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, | 3009 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, |