This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]