Author: Carl Friedrich Bolz <[email protected]>
Branch: faster-str-of-bigint
Changeset: r64998:c10714392297
Date: 2013-06-26 11:40 +0200
http://bitbucket.org/pypy/pypy/changeset/c10714392297/

Log:    reinstate the use of an array for the result of
        _format_base2_notzero it's faster and I couldn't be bothered to find
        out how to compute the result not in reverse

diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -1974,59 +1974,38 @@
 BASE10 = '0123456789'
 BASE16 = '0123456789abcdef'
 
-def _format(a, digits, prefix='', suffix=''):
-    """
-    Convert a bigint object to a string, using a given conversion base.
-    Return a string object.
-    """
-
-
-    # Compute a rough upper bound for the length of the string
-    i = base
-    bits = 0
-    while i > 1:
-        bits += 1
-        i >>= 1
-    i = 5 + len(prefix) + len(suffix) + (size_a*SHIFT + bits-1) // bits
-    s = [chr(0)] * i
-    p = i
-    j = len(suffix)
-    while j > 0:
-        p -= 1
-        j -= 1
-        s[p] = suffix[j]
-
-    if a.sign == 0:
-        p -= 1
-        s[p] = '0'
-
-def _format_base2(a, digits, prefix, suffix):
+def _format_base2_notzero(a, digits, prefix='', suffix=''):
+        base = len(digits)
         # JRH: special case for power-of-2 bases
-        output = StringBuilder()
-        if a.sign < 0:
-            output.append('-')
-        output.append(prefix)
-        base = len(digits)
-        size_a = a.numdigits()
         accum = 0
         accumbits = 0  # # of bits in accum
-        basebits = 1   # # of bits in base-1
+        basebits = 0
         i = base
-        while 1:
+        while i > 1:
+            basebits += 1
             i >>= 1
-            if i <= 1:
-                break
-            basebits += 1
+
+        # Compute a rough upper bound for the length of the string
+        size_a = a.numdigits()
+        i = 5 + len(prefix) + len(suffix) + (size_a*SHIFT + basebits-1) // 
basebits
+        result = [chr(0)] * i
+        next_char_index = i
+        j = len(suffix)
+        while j > 0:
+            next_char_index -= 1
+            j -= 1
+            result[next_char_index] = suffix[j]
 
         i = 0
         while i < size_a:
             accum |= a.widedigit(i) << accumbits
             accumbits += SHIFT
             assert accumbits >= basebits
-            out = []
             while 1:
                 cdigit = intmask(accum & (base - 1))
-                out.append(digits[cdigit])
+                next_char_index -= 1
+                assert next_char_index >= 0
+                result[next_char_index] = digits[cdigit]
                 accumbits -= basebits
                 accum >>= basebits
                 if i < size_a - 1:
@@ -2035,11 +2014,20 @@
                 else:
                     if accum <= 0:
                         break
-            out.reverse()
-            output.append("".join(out))
             i += 1
-        output.append(suffix)
-        return output.build()
+        j = len(prefix)
+        while j > 0:
+            next_char_index -= 1
+            j -= 1
+            result[next_char_index] = prefix[j]
+
+        if a.sign < 0:
+            next_char_index -= 1
+            result[next_char_index] = '-'
+
+        assert next_char_index >= 0    # otherwise, buffer overflow (this is 
also a
+                         # hint for the annotator for the slice below)
+        return ''.join(result[next_char_index:])
 
 _FORMAT_MINDIGITS = 5 # 36 ** 5 fits in 32 bits, there may be a better choice 
for this
 
@@ -2080,7 +2068,7 @@
     base = len(digits)
     assert base >= 2 and base <= 36
     if (base & (base - 1)) == 0:
-        return _format_base2(x, digits, prefix, suffix)
+        return _format_base2_notzero(x, digits, prefix, suffix)
     negative = x.sign < 0
     if negative:
         x = x.neg()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to