From ce26657b5d7e77d851ed9267d554f4f48e43a0b6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Fri, 18 Mar 2022 11:43:10 +0100 Subject: [PATCH] Speed up number-to-string for fixnums MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. --- src/data.c | 28 ++++++++++++++++++++++------ 1 file 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, -- 2.39.2