[pypy-commit] pypy faster-str-of-bigint: use a string builder

cfbolz noreply at buildbot.pypy.org
Wed Jun 26 09:03:52 CEST 2013


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: faster-str-of-bigint
Changeset: r64993:c18866b5ecce
Date: 2013-06-25 22:21 +0200
http://bitbucket.org/pypy/pypy/changeset/c18866b5ecce/

Log:	use a string builder

diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -2191,15 +2191,26 @@
 
 _FORMAT_DECIMAL_MINDIGITS = 9 # fits in 32 bits, there may be a better choice for this
 
-def _format_decimal_recursive(x, i, output, pts):
-    if i < 0: # bottomed out with min_digit sized pieces
-        if output or x.gt(NULLRBIGINT):
+def _format_decimal_recursive(x, i, output, pts, negative):
+    # bottomed out with min_digit sized pieces
+    # use str of ints
+    if i < 0:
+        # this checks whether any digit has been appended yet
+        # the extra char for negative rbigints is the '-'
+        if output.getlength() == negative:
+            if x.sign == 0:
+                pass
+            else:
+                s = str(x.toint())
+                output.append(s)
+        else:
             s = str(x.toint())
-            output.append("0"*(_FORMAT_DECIMAL_MINDIGITS - len(s)) + s) # note that this appends in inorder
+            output.append_multiple_char("0", _FORMAT_DECIMAL_MINDIGITS - len(s))
+            output.append(s)
     else:
         top,bot = x.divmod(pts[i]) # split the number
-        _format_decimal_recursive(top,i-1, output, pts)
-        _format_decimal_recursive(bot,i-1, output, pts)
+        _format_decimal_recursive(top, i-1, output, pts, negative)
+        _format_decimal_recursive(bot, i-1, output, pts, negative)
 
 def _format_decimal_new(x, addL=False):
     if x.sign == 0:
@@ -2213,17 +2224,20 @@
     two = rbigint.fromint(2)
 
     pts = [ten.pow(rbigint.fromint(_FORMAT_DECIMAL_MINDIGITS))]
+    stringsize = _FORMAT_DECIMAL_MINDIGITS
     while pts[-1].lt(x):
         pts.append(pts[-1].pow(two))
+        stringsize *= 2
     pts.pop() # remove first 10**2**i greater than x
-    output = []
 
-    _format_decimal_recursive(x,len(pts)-1, output, pts)
-    # strip leading zeros, we can probably do this more elegantly
-    output = "".join(output)
-    while len(output) > 1 and output[0] == "0":
-        output = output[1:]
-    return "-" * negative + output + "L" * addL
+    output = StringBuilder(stringsize)
+    if negative:
+        output.append('-')
+    _format_decimal_recursive(x,len(pts)-1, output, pts, negative)
+
+    if addL:
+        output.append('L')
+    return output.build()
 
 
 def _bitwise(a, op, b): # '&', '|', '^'


More information about the pypy-commit mailing list