[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