Author: stian
Branch: improve-rbigint
Changeset: r56347:cd82209a05cb
Date: 2012-07-05 20:23 +0200
http://bitbucket.org/pypy/pypy/changeset/cd82209a05cb/
Log: Improve the general speed of pow, special case 0 ** something and
something ** 0, along with negative numbers.
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -558,6 +558,11 @@
# XXX failed to implement
raise ValueError("bigint pow() too negative")
+ if b.sign == 0:
+ return ONERBIGINT
+ elif a.sign == 0:
+ return NULLRBIGINT
+
size_b = b.numdigits()
if c is not None:
@@ -574,7 +579,7 @@
# if modulus == 1:
# return 0
if c.numdigits() == 1 and c.digit(0) == 1:
- return rbigint()
+ return NULLRBIGINT
# if base < 0:
# base = base % modulus
@@ -583,18 +588,23 @@
a = a.mod(c)
- elif size_b == 1 and a.sign == 1:
+ elif size_b == 1:
digit = b.digit(0)
if digit == 0:
- return ONERBIGINT
+ return ONERBIGINT if a.sign == 1 else ONENEGATIVERBIGINT
elif digit == 1:
return a
elif a.numdigits() == 1:
adigit = a.digit(0)
if adigit == 1:
+ if a.sign == -1 and digit % 2:
+ return ONENEGATIVERBIGINT
return ONERBIGINT
elif adigit & (adigit - 1) == 0:
- return a.lshift(((digit-1)*(ptwotable[adigit]-1)) +
digit-1)
+ ret = a.lshift(((digit-1)*(ptwotable[adigit]-1)) + digit-1)
+ if a.sign == -1 and not digit % 2:
+ ret.sign = 1
+ return ret
# At this point a, b, and c are guaranteed non-negative UNLESS
# c is NULL, in which case a may be negative. */
@@ -848,6 +858,7 @@
self.sign, self.str())
ONERBIGINT = rbigint([ONEDIGIT], 1)
+ONENEGATIVERBIGINT = rbigint([ONEDIGIT], -1)
NULLRBIGINT = rbigint()
#_________________________________________________________________
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
@@ -29,21 +29,21 @@
Sum: 901.7231250000001
Pypy with improvements:
- 2.884540
- 2.499774
- 3.796117
- 1.681326
- 4.060521
- 9.696996
- 1.643792
- 4.045248
- 4.714733
- 6.589811
- 0.039319
- 3.503355
- 8.266362
- 5.044856
- Sum: 58.466750
+ 2.867820
+ 2.523047
+ 3.848003
+ 1.682992
+ 4.099669
+ 9.233212
+ 1.622695
+ 4.026895
+ 4.708891
+ 6.542558
+ 0.039864
+ 3.508814
+ 8.225711
+ 5.009382
+ Sum: 57.939553
A pure python form of those tests where also run
Improved pypy | Pypy | CPython 2.7.3
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit