[pypy-commit] pypy improve-rbigint: Vast improvement, especially to add and mul by self
stian
noreply at buildbot.pypy.org
Sat Jul 21 18:41:52 CEST 2012
Author: stian
Branch: improve-rbigint
Changeset: r56361:4ffb2cad4eaa
Date: 2012-07-12 17:47 +0200
http://bitbucket.org/pypy/pypy/changeset/4ffb2cad4eaa/
Log: Vast improvement, especially to add and mul by self
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -145,6 +145,7 @@
_check_digits(digits)
make_sure_not_resized(digits)
self._digits = digits
+ self.size = len(digits)
self.sign = sign
def digit(self, x):
@@ -172,7 +173,7 @@
setdigit._always_inline_ = True
def numdigits(self):
- return len(self._digits)
+ return self.size
numdigits._always_inline_ = True
@staticmethod
@@ -755,7 +756,7 @@
assert newsize >= 0
z.setdigit(newsize, accum)
- z._positivenormalize()
+ z._normalize()
return z
lshift._always_inline_ = True # It's so fast that it's always benefitial.
@@ -775,7 +776,7 @@
accum >>= SHIFT
z.setdigit(oldsize, accum)
- z._positivenormalize()
+ z._normalize()
return z
lqshift._always_inline_ = True # It's so fast that it's always benefitial.
@@ -810,7 +811,7 @@
z.setdigit(i, newdigit)
i += 1
wordshift += 1
- z._positivenormalize()
+ z._normalize()
return z
rshift._always_inline_ = True # It's so fast that it's always benefitial.
@@ -859,6 +860,7 @@
i = c = self.numdigits()
if i == 0:
self.sign = 0
+ self.size = 1
self._digits = [NULLDIGIT]
return
@@ -866,23 +868,12 @@
i -= 1
assert i > 0
if i != c:
- self._digits = self._digits[:i]
+ self.size = i
if self.numdigits() == 1 and self._digits[0] == NULLDIGIT:
self.sign = 0
+ self._digits = [NULLDIGIT]
- #_normalize._always_inline_ = True
-
- def _positivenormalize(self):
- """ This function assumes numdigits > 0. Good for shifts and such """
- i = c = self.numdigits()
- while i > 1 and self._digits[i - 1] == NULLDIGIT:
- i -= 1
- assert i > 0
- if i != c:
- self._digits = self._digits[:i]
- if self.numdigits() == 1 and self._digits[0] == NULLDIGIT:
- self.sign = 0
- _positivenormalize._always_inline_ = True
+ _normalize._always_inline_ = True
def bit_length(self):
i = self.numdigits()
@@ -1005,7 +996,7 @@
carry >>= SHIFT
i += 1
z.setdigit(i, carry)
- z._positivenormalize()
+ z._normalize()
return z
def _x_sub(a, b):
@@ -1105,7 +1096,7 @@
z.setdigit(pz, z.widedigit(pz) + carry)
assert (carry >> SHIFT) == 0
i += 1
- z._positivenormalize()
+ z._normalize()
return z
elif digit and digit & (digit - 1) == 0:
@@ -1131,7 +1122,7 @@
z.setdigit(pz, z.widedigit(pz) + carry)
assert (carry >> SHIFT) == 0
i += 1
- z._positivenormalize()
+ z._normalize()
return z
@@ -1219,7 +1210,7 @@
_v_iadd(ret, shift, i, r1, r1.numdigits())
_v_iadd(ret, shift * 3, i, r3, r3.numdigits())
- ret._positivenormalize()
+ ret._normalize()
return ret
@@ -1236,8 +1227,8 @@
lo = rbigint(n._digits[:size_lo], 1)
hi = rbigint(n._digits[size_lo:], 1)
- lo._positivenormalize()
- hi._positivenormalize()
+ lo._normalize()
+ hi._normalize()
return hi, lo
def _k_mul(a, b):
@@ -1331,7 +1322,7 @@
# See the (*) comment after this function.
_v_iadd(ret, shift, i, t3, t3.numdigits())
- ret._positivenormalize()
+ ret._normalize()
return ret
""" (*) Why adding t3 can't "run out of room" above.
@@ -1425,7 +1416,7 @@
bsize -= nbtouse
nbdone += nbtouse
- ret._positivenormalize()
+ ret._normalize()
return ret
def _inplace_divrem1(pout, pin, n, size=0):
diff --git a/pypy/translator/goal/targetbigintbenchmark.py b/pypy/translator/goal/targetbigintbenchmark.py
--- a/pypy/translator/goal/targetbigintbenchmark.py
+++ b/pypy/translator/goal/targetbigintbenchmark.py
@@ -35,24 +35,24 @@
Sum: 142.686547
Pypy with improvements:
- mod by 2: 0.007535
- mod by 10000: 3.686409
- mod by 1024 (power of two): 0.011153
- Div huge number by 2**128: 2.162245
- rshift: 2.211261
- lshift: 2.711231
- Floordiv by 2: 1.481641
- Floordiv by 3 (not power of two): 4.067045
- 2**500000: 0.155143
- (2**N)**5000000 (power of two): 0.098826
- 10000 ** BIGNUM % 100 1.742109
- i = i * i: 4.836238
- n**10000 (not power of two): 6.196422
- Power of two ** power of two: 0.038207
- v = v * power of two 3.629006
- v = v * v 8.220768
- v = v + v 4.998141
- Sum: 46.253380
+ mod by 2: 0.005984
+ mod by 10000: 3.664320
+ mod by 1024 (power of two): 0.011461
+ Div huge number by 2**128: 2.146720
+ rshift: 2.319716
+ lshift: 1.344974
+ Floordiv by 2: 1.597306
+ Floordiv by 3 (not power of two): 4.197931
+ 2**500000: 0.033942
+ (2**N)**5000000 (power of two): 0.050020
+ 10000 ** BIGNUM % 100 1.960709
+ i = i * i: 3.902392
+ n**10000 (not power of two): 5.980987
+ Power of two ** power of two: 0.013227
+ v = v * power of two 3.478328
+ v = v * v 6.345457
+ v = v + v 2.770636
+ Sum: 39.824111
A pure python form of those tests where also run
Improved pypy | Pypy | CPython 2.7.3
More information about the pypy-commit
mailing list