]> git.eshelyaron.com Git - emacs.git/commitdiff
Speed up number-to-string for fixnums
authorMattias Engdegård <mattiase@acm.org>
Fri, 18 Mar 2022 10:43:10 +0000 (11:43 +0100)
committerMattias Engdegård <mattiase@acm.org>
Fri, 18 Mar 2022 10:54:08 +0000 (11:54 +0100)
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

index 1526cc0c73748b7ee334ca7af985f53e4a4512c2..6eda0089702ac21c658f1ff65a4f348c8f5d644b 100644 (file)
@@ -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,