[pypy-commit] pypy improve-rbigint: Re-enable the a == b strategy. Apperently it works, thou, not 2x speedup, but 16% on HUGE ints

stian noreply at buildbot.pypy.org
Sat Jul 21 18:40:59 CEST 2012


Author: stian
Branch: improve-rbigint
Changeset: r56314:ce7c8412e355
Date: 2012-06-22 02:57 +0200
http://bitbucket.org/pypy/pypy/changeset/ce7c8412e355/

Log:	Re-enable the a == b strategy. Apperently it works, thou, not 2x
	speedup, but 16% on HUGE ints

diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -857,16 +857,26 @@
     """
 
     size_a = a.numdigits()
-    size_b = b.numdigits()
-    """
-    # Code below actually runs slower (about 20%). Dunno why, since it shouldn't.
+
+    if size_a == 1:
+        # Special case.
+        digit = a.digit(0)
+        if digit == 0:
+            return rbigint([NULLDIGIT], 1)
+        elif digit == 1:
+            return rbigint(b._digits[:], 1)
+        elif digit & (digit - 1) == 0:
+            return b.lqshift(ptwotable[digit])
+        
+    size_b = b.numdigits()    
+    z = rbigint([NULLDIGIT] * (size_a + size_b), 1)
+    i = 0
     if a is b:
         # Efficient squaring per HAC, Algorithm 14.16:
         # http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
         # Gives slightly less than a 2x speedup when a == b,
         # via exploiting that each entry in the multiplication
         # pyramid appears twice (except for the size_a squares).
-        i = 0
         while i < size_a:
             f = a.widedigit(i)
             pz = i << 1
@@ -898,36 +908,25 @@
                 z.setdigit(pz, z.widedigit(pz) + carry)
             assert (carry >> SHIFT) == 0
             i += 1
-    else:"""
-    if size_a == 1:
-        # Special case.
-        digit = a.digit(0)
-        if digit == 0:
-            return rbigint([NULLDIGIT], 1)
-        elif digit == 1:
-            return rbigint(b._digits[:], 1)
-        elif digit & (digit - 1) == 0:
-            return b.lqshift(ptwotable[digit])
-    
-    z = rbigint([NULLDIGIT] * (size_a + size_b), 1)
-    # gradeschool long mult
-    i = 0
-    while i < size_a:
-        carry = 0
-        f = a.widedigit(i)
-        pz = i
-        pb = 0
-        while pb < size_b:
-            carry += z.widedigit(pz) + b.widedigit(pb) * f
-            pb += 1
-            z.setdigit(pz, carry)
-            pz += 1
-            carry >>= SHIFT
-            assert carry <= MASK
-        if carry:
-            z.setdigit(pz, z.widedigit(pz) + carry)
-        assert (carry >> SHIFT) == 0
-        i += 1
+    else:
+        # gradeschool long mult
+        while i < size_a:
+            carry = 0
+            f = a.widedigit(i)
+            pz = i
+            pb = 0
+            while pb < size_b:
+                carry += z.widedigit(pz) + b.widedigit(pb) * f
+                pb += 1
+                z.setdigit(pz, carry)
+                pz += 1
+                carry >>= SHIFT
+                assert carry <= MASK
+            if carry:
+                z.setdigit(pz, z.widedigit(pz) + carry)
+            assert (carry >> SHIFT) == 0
+            i += 1
+            
     z._normalize()
     return z
 


More information about the pypy-commit mailing list