From 4d61badad15e8213c84798b85f10868fc48b94ee Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Fri, 18 Mar 2022 13:58:36 +0100 Subject: [PATCH] Speed up fixnum printing Use the new number-to-string code to speed up fixnum printing, with similar results (often more than twice as fast as before). * src/data.c (Fnumber_to_string): Move fixnum conversion to... (fixnum_to_string): ... this new function. * src/lisp.h: (fixnum_to_string): External declaration. * src/print.c (print_object): Use fixnum_to_string instead of sprintf. --- src/data.c | 38 ++++++++++++++++++++++++-------------- src/lisp.h | 1 + src/print.c | 6 ++++-- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/data.c b/src/data.c index 6eda0089702..23b0e7c29d9 100644 --- a/src/data.c +++ b/src/data.c @@ -2968,6 +2968,29 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) return val; } +/* Render NUMBER in decimal into BUFFER which ends right before END. + Return the start of the string; the end is always at END. + The string is not null-terminated. */ +char * +fixnum_to_string (EMACS_INT number, char *buffer, char *end) +{ + EMACS_INT x = number; + bool negative = x < 0; + if (negative) + x = -x; + char *p = end; + do + { + eassume (p > buffer && p - 1 < end); + *--p = '0' + x % 10; + x /= 10; + } + while (x); + if (negative) + *--p = '-'; + return p; +} + DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, doc: /* Return the decimal representation of NUMBER as a string. Uses a minus sign if negative. @@ -2978,21 +3001,8 @@ NUMBER may be an integer or a floating point 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 = '-'; + char *p = fixnum_to_string (XFIXNUM (number), buffer, end); return make_unibyte_string (p, end - p); } diff --git a/src/lisp.h b/src/lisp.h index 21709b12598..e4d156c0f45 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -622,6 +622,7 @@ extern AVOID args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object); extern AVOID wrong_type_argument (Lisp_Object, Lisp_Object); extern Lisp_Object default_value (Lisp_Object symbol); extern void defalias (Lisp_Object symbol, Lisp_Object definition); +extern char *fixnum_to_string (EMACS_INT number, char *buffer, char *end); /* Defined in emacs.c. */ diff --git a/src/print.c b/src/print.c index 704fc278f2d..4a68d15fe02 100644 --- a/src/print.c +++ b/src/print.c @@ -2060,8 +2060,10 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) } else { - int len = sprintf (buf, "%"pI"d", i); - strout (buf, len, len, printcharfun); + char *end = buf + sizeof buf; + char *start = fixnum_to_string (i, buf, end); + ptrdiff_t len = end - start; + strout (start, len, len, printcharfun); } } break; -- 2.39.2