Mercurial > hg > xemacs-beta
changeset 577:910449c92002
[xemacs-hg @ 2001-05-25 10:04:26 by hrvojen]
Commit the new, faster version of long_to_string.
Published in <sxsofsiy5ze.fsf@florida.arsdigita.de>.
author | hrvojen |
---|---|
date | Fri, 25 May 2001 10:04:29 +0000 |
parents | 6db80f4ab17c |
children | 190b164ddcac |
files | src/ChangeLog src/doprnt.c src/lisp.h src/print.c |
diffstat | 4 files changed, 111 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Fri May 25 05:42:26 2001 +0000 +++ b/src/ChangeLog Fri May 25 10:04:29 2001 +0000 @@ -1,3 +1,11 @@ +2001-05-24 Hrvoje Niksic <hniksic@arsdigita.com> + + * doprnt.c (emacs_doprnt_1): long_to_string doesn't return a + value. + + * print.c (long_to_string): New, faster implementation. Revert + change from 2000-11-22. + 2001-05-25 Martin Buchholz <martin@xemacs.org> * process-unix.c (unix_canonicalize_host_name): Fix compile warnings.
--- a/src/doprnt.c Fri May 25 05:42:26 2001 +0000 +++ b/src/doprnt.c Fri May 25 10:04:29 2001 +0000 @@ -614,11 +614,15 @@ if (spec->zero_flag) *p++ = '0'; if (spec->minwidth >= 0) - p = long_to_string (p, spec->minwidth); + { + long_to_string (p, spec->minwidth); + p += strlen (p); + } if (spec->precision >= 0) { *p++ = '.'; - p = long_to_string (p, spec->precision); + long_to_string (p, spec->precision); + p += strlen (p); } if (strchr (double_converters, ch))
--- a/src/lisp.h Fri May 25 05:42:26 2001 +0000 +++ b/src/lisp.h Fri May 25 10:04:29 2001 +0000 @@ -2835,7 +2835,7 @@ void print_cons (Lisp_Object, Lisp_Object, int); void print_vector (Lisp_Object, Lisp_Object, int); void print_string (Lisp_Object, Lisp_Object, int); -char *long_to_string (char *, long); +void long_to_string (char *, long); void print_internal (Lisp_Object, Lisp_Object, int); void print_symbol (Lisp_Object, Lisp_Object, int); void print_float (Lisp_Object, Lisp_Object, int);
--- a/src/print.c Fri May 25 05:42:26 2001 +0000 +++ b/src/print.c Fri May 25 10:04:29 2001 +0000 @@ -940,59 +940,114 @@ } #endif /* LISP_FLOAT_TYPE */ -/* Print NUMBER to BUFFER. - This is equivalent to sprintf (buffer, "%ld", number), only much faster. +#define ONE_DIGIT(figure) *p++ = n / (figure) + '0' +#define ONE_DIGIT_ADVANCE(figure) (ONE_DIGIT (figure), n %= (figure)) + +#define DIGITS_1(figure) ONE_DIGIT (figure) +#define DIGITS_2(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_1 ((figure) / 10) +#define DIGITS_3(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_2 ((figure) / 10) +#define DIGITS_4(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_3 ((figure) / 10) +#define DIGITS_5(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_4 ((figure) / 10) +#define DIGITS_6(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_5 ((figure) / 10) +#define DIGITS_7(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_6 ((figure) / 10) +#define DIGITS_8(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_7 ((figure) / 10) +#define DIGITS_9(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_8 ((figure) / 10) +#define DIGITS_10(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_9 ((figure) / 10) + +/* DIGITS_<11-20> are only used on machines with 64-bit longs. */ - BUFFER should accept 24 bytes. This should suffice for the longest - numbers on 64-bit machines, including the `-' sign and the trailing - '\0'. Returns a pointer to the trailing '\0'. */ -char * +#define DIGITS_11(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_10 ((figure) / 10) +#define DIGITS_12(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_11 ((figure) / 10) +#define DIGITS_13(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_12 ((figure) / 10) +#define DIGITS_14(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_13 ((figure) / 10) +#define DIGITS_15(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_14 ((figure) / 10) +#define DIGITS_16(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_15 ((figure) / 10) +#define DIGITS_17(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_16 ((figure) / 10) +#define DIGITS_18(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_17 ((figure) / 10) +#define DIGITS_19(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_18 ((figure) / 10) + +/* Print NUMBER to BUFFER in base 10. This is completely equivalent + to `sprintf(buffer, "%ld", number)', only much faster. + + The speedup may make a difference in programs that frequently + convert numbers to strings. Some implementations of sprintf, + particularly the one in GNU libc, have been known to be extremely + slow compared to this function. + + BUFFER should accept as many bytes as you expect the number to take + up. On machines with 64-bit longs the maximum needed size is 24 + bytes. That includes the worst-case digits, the optional `-' sign, + and the trailing \0. */ + +void long_to_string (char *buffer, long number) { + char *p = buffer; + long n = number; + #if (SIZEOF_LONG != 4) && (SIZEOF_LONG != 8) - /* Huh? */ - sprintf (buffer, "%ld", number); - return buffer + strlen (buffer); -#else /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */ - char *p = buffer; - int force = 0; + /* We are running in a strange or misconfigured environment. Let + sprintf cope with it. */ + sprintf (buffer, "%ld", n); +#else /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */ - if (number < 0) + if (n < 0) { *p++ = '-'; - number = -number; + n = -n; } -#define FROB(figure) do { \ - if (force || number >= figure) \ - *p++ = number / figure + '0', number %= figure, force = 1; \ - } while (0) -#if SIZEOF_LONG == 8 - FROB (1000000000000000000L); - FROB (100000000000000000L); - FROB (10000000000000000L); - FROB (1000000000000000L); - FROB (100000000000000L); - FROB (10000000000000L); - FROB (1000000000000L); - FROB (100000000000L); - FROB (10000000000L); -#endif /* SIZEOF_LONG == 8 */ - FROB (1000000000); - FROB (100000000); - FROB (10000000); - FROB (1000000); - FROB (100000); - FROB (10000); - FROB (1000); - FROB (100); - FROB (10); -#undef FROB - *p++ = number + '0'; + if (n < 10) { DIGITS_1 (1); } + else if (n < 100) { DIGITS_2 (10); } + else if (n < 1000) { DIGITS_3 (100); } + else if (n < 10000) { DIGITS_4 (1000); } + else if (n < 100000) { DIGITS_5 (10000); } + else if (n < 1000000) { DIGITS_6 (100000); } + else if (n < 10000000) { DIGITS_7 (1000000); } + else if (n < 100000000) { DIGITS_8 (10000000); } + else if (n < 1000000000) { DIGITS_9 (100000000); } +#if SIZEOF_LONG == 4 + /* ``if (1)'' serves only to preserve editor indentation. */ + else if (1) { DIGITS_10 (1000000000); } +#else /* SIZEOF_LONG != 4 */ + else if (n < 10000000000L) { DIGITS_10 (1000000000L); } + else if (n < 100000000000L) { DIGITS_11 (10000000000L); } + else if (n < 1000000000000L) { DIGITS_12 (100000000000L); } + else if (n < 10000000000000L) { DIGITS_13 (1000000000000L); } + else if (n < 100000000000000L) { DIGITS_14 (10000000000000L); } + else if (n < 1000000000000000L) { DIGITS_15 (100000000000000L); } + else if (n < 10000000000000000L) { DIGITS_16 (1000000000000000L); } + else if (n < 100000000000000000L) { DIGITS_17 (10000000000000000L); } + else if (n < 1000000000000000000L) { DIGITS_18 (100000000000000000L); } + else { DIGITS_19 (1000000000000000000L); } +#endif /* SIZEOF_LONG != 4 */ + *p = '\0'; - return p; #endif /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */ } + +#undef ONE_DIGIT +#undef ONE_DIGIT_ADVANCE + +#undef DIGITS_1 +#undef DIGITS_2 +#undef DIGITS_3 +#undef DIGITS_4 +#undef DIGITS_5 +#undef DIGITS_6 +#undef DIGITS_7 +#undef DIGITS_8 +#undef DIGITS_9 +#undef DIGITS_10 +#undef DIGITS_11 +#undef DIGITS_12 +#undef DIGITS_13 +#undef DIGITS_14 +#undef DIGITS_15 +#undef DIGITS_16 +#undef DIGITS_17 +#undef DIGITS_18 +#undef DIGITS_19 static void print_vector_internal (const char *start, const char *end,