This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
[PATCH] Speed-up decimal formatting of integers.
- From: Sergei Organov <osv at javad dot com>
- To: ecos-patches at ecos dot sourceware dot org
- Date: Mon, 05 Feb 2007 20:25:27 +0300
- Subject: [PATCH] Speed-up decimal formatting of integers.
Current vfnprintf() implementation always uses long long arithmetic when
formatting integers. While this is acceptable for formatting in
hexadecimal and octal, for formatting in decimal it results in using
of generic long long integer division function (GCC built-in) that is
very time consuming, especially for targets without hardware integer
division.
In addition, changing the type of division from "long long" to "long"
allows GCC to replace the division by 10 by the special fast inline
algorithm that avoids using of generic division routine entirely.
The attached patch gets rid of long long division, unless long long
argument is to be printed.
Index: packages/language/c/libc/stdio/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/language/c/libc/stdio/current/ChangeLog,v
retrieving revision 1.40
diff -u -a -r1.40 ChangeLog
--- packages/language/c/libc/stdio/current/ChangeLog 27 Jan 2007 13:53:37 -0000 1.40
+++ packages/language/c/libc/stdio/current/ChangeLog 5 Feb 2007 17:07:32 -0000
@@ -1,3 +1,10 @@
+2007-02-05 Sergei Organov <osv@javad.com>
+
+ * src/output/vfnprintf.cxx (vfnprintf): while formatting integers
+ in decimal, convert the value to unsigned long from unsigned long
+ long before processing, unless we actually print long long
+ argument. This tremendously speeds-up the formatting.
+
2007-01-16 Sergei Organov <osv@javad.com>
Speed-up [v]s[n]printf() functions by a factor of about 2+. In
Index: packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx,v
retrieving revision 1.11
diff -u -a -r1.11 vfnprintf.cxx
--- packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx 27 Jan 2007 13:53:37 -0000 1.11
+++ packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx 5 Feb 2007 17:07:33 -0000
@@ -553,14 +553,26 @@
break;
case DEC:
- /* many numbers are 1 digit */
- while (_uquad >= 10) {
- /* The following is usually faster than using a modulo */
- u_quad_t next = _uquad / 10;
- *--cp = to_char(_uquad - (next * 10));
- _uquad = next;
+ if (!(flags & QUADINT)) {
+ /* many numbers are 1 digit */
+ unsigned long v = (unsigned long)_uquad;
+ while (v >= 10) {
+ /* The following is usually faster than using a modulo */
+ unsigned long next = v / 10;
+ *--cp = to_char(v - (next * 10));
+ v = next;
+ }
+ *--cp = to_char(v);
+ }
+ else {
+ while (_uquad >= 10) {
+ /* The following is usually faster than using a modulo */
+ u_quad_t next = _uquad / 10;
+ *--cp = to_char(_uquad - (next * 10));
+ _uquad = next;
+ }
+ *--cp = to_char(_uquad);
}
- *--cp = to_char(_uquad);
break;
case HEX: