[pypy-commit] pypy improve-rbigint: Reduce operations on mod and floordiv (without power of two) = more speed

stian noreply at buildbot.pypy.org
Sat Jul 21 18:41:15 CEST 2012


Author: stian
Branch: improve-rbigint
Changeset: r56328:1d2cb7e2302d
Date: 2012-06-24 23:38 +0200
http://bitbucket.org/pypy/pypy/changeset/1d2cb7e2302d/

Log:	Reduce operations on mod and floordiv (without power of two) = more
	speed

diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -161,8 +161,8 @@
         # This function is marked as pure, so you must not call it and
         # then modify the result.
         if b:
-            return rbigint([ONEDIGIT], 1)
-        return rbigint()
+            return ONERBIGINT
+        return NULLRBIGINT
 
     @staticmethod
     def fromlong(l):
@@ -421,14 +421,18 @@
                 div = self.rshift(ptwotable[digit])
                 return div
             
-        div, mod = self.divmod(other)
+        div, mod = _divrem(self, other)
+        if mod.sign * other.sign == -1:
+            div = div.sub(ONERBIGINT)
         return div
 
     def div(self, other):
         return self.floordiv(other)
 
     def mod(self, other):
-        div, mod = self.divmod(other)
+        div, mod = _divrem(self, other)
+        if mod.sign * other.sign == -1:
+            mod = mod.add(other)
         return mod
 
     def divmod(v, w):
@@ -451,7 +455,7 @@
         div, mod = _divrem(v, w)
         if mod.sign * w.sign == -1:
             mod = mod.add(w)
-            div = div.sub(rbigint([_store_digit(1)], 1))
+            div = div.sub(ONERBIGINT)
         return div, mod
 
     def pow(a, b, c=None):
@@ -498,13 +502,13 @@
         elif size_b == 1 and a.sign == 1:
             digit = b.digit(0)
             if digit == 0:
-                return rbigint([ONEDIGIT], 1)
+                return ONERBIGINT
             elif digit == 1:
                 return a
             elif a.numdigits() == 1:
                 adigit = a.digit(0)
                 if adigit == 1:
-                    return rbigint([ONEDIGIT], 1)
+                    return ONERBIGINT
                 elif adigit & (adigit - 1) == 0:
                     return a.lshift(((digit-1)*(ptwotable[adigit]-1)) + digit-1)
                 
@@ -745,6 +749,9 @@
         return "<rbigint digits=%s, sign=%s, %s>" % (self._digits,
                                                      self.sign, self.str())
 
+ONERBIGINT = rbigint([ONEDIGIT], 1)
+NULLRBIGINT = rbigint()
+
 #_________________________________________________________________
 
 # Helper Functions
@@ -866,7 +873,7 @@
         while i >= 0 and a.digit(i) == b.digit(i):
             i -= 1
         if i < 0:
-            return rbigint()
+            return NULLRBIGINT
         if a.digit(i) < b.digit(i):
             sign = -1
             a, b = b, a
@@ -1464,9 +1471,7 @@
         (size_a == size_b and
          a.digit(size_a-1) < b.digit(size_b-1))):
         # |a| < |b|
-        z = rbigint()   # result is 0
-        rem = a
-        return z, rem
+        return NULLRBIGINT, a# result is 0
     if size_b == 1:
         z, urem = _divrem1(a, b.digit(0))
         rem = rbigint([_store_digit(urem)], int(urem != 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
@@ -11,6 +11,7 @@
         A cutout with some benchmarks.
         Pypy default:
         5.147583
+        5.139127
         484.5688
         334.611903
         8.637287
@@ -22,16 +23,17 @@
         6.647562
 
         Pypy with improvements:
-        2.307890
-        9.451896
-        1.122038
-        5.787821
-        9.937016
-        14.927304
-        0.016683
-        12.018289
-        14.261727
-        6.434917
+        2.291724
+        4.616600
+        9.538857
+        1.102726
+        4.820049
+        9.899771
+        14.733251
+        0.016657
+        11.992919
+        14.144412
+        6.404446
 
     """
 
@@ -44,6 +46,14 @@
     print time() - t
     
     t = time()
+    num = rbigint.fromint(100000000)
+    for n in xrange(80000000):
+        rbigint.floordiv(num, rbigint.fromint(3))
+        
+
+    print time() - t
+    
+    t = time()
     num = rbigint.fromint(10000000)
     for n in xrange(10000):
         rbigint.pow(rbigint.fromint(2), num)


More information about the pypy-commit mailing list