Author: stian
Branch: improve-rbigint
Changeset: r56359:73b4cd7f0ca0
Date: 2012-07-08 00:03 +0200
http://bitbucket.org/pypy/pypy/changeset/73b4cd7f0ca0/

Log:    Fix a broken test, and optimize mod, and refactor benchmarks to be
        more explainable

diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -511,7 +511,39 @@
 
     @jit.elidable
     def mod(self, other):
-        div, mod = _divrem(self, other)
+        if self.sign == 0:
+            return NULLRBIGINT
+        
+        if other.sign != 0 and other.numdigits() == 1:
+            digit = other.digit(0)
+            if digit == 1:
+                return NULLRBIGINT
+            elif digit == 2:
+                modm = self.digit(0) % digit
+                if modm:
+                    if other.sign < 0:
+                        return ONENEGATIVERBIGINT
+                    return ONERBIGINT
+                return NULLRBIGINT
+            elif digit & (digit - 1) == 0:
+                mod = self.and_(_x_sub(other, ONERBIGINT))
+            else:
+                # Perform
+                size = self.numdigits() - 1
+                if size > 0:
+                    rem = self.widedigit(size)
+                    size -= 1
+                    while size >= 0:
+                        rem = ((rem << SHIFT) + self.widedigit(size)) % digit
+                        size -= 1
+                else:
+                    rem = self.digit(0) % digit
+                    
+                if rem == 0:
+                    return NULLRBIGINT
+                mod = rbigint([_store_digit(rem)], -1 if self.sign < 0 else 1)
+        else:
+            div, mod = _divrem(self, other)
         if mod.sign * other.sign == -1:
             mod = mod.add(other)
         return mod
diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py
--- a/pypy/rlib/test/test_rbigint.py
+++ b/pypy/rlib/test/test_rbigint.py
@@ -94,6 +94,7 @@
                 rl_op2 = rbigint.fromint(op2)
                 r1 = rl_op1.mod(rl_op2)
                 r2 = op1 % op2
+                print op1, op2
                 assert r1.tolong() == r2
 
     def test_pow(self):
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,24 @@
         Sum: 901.7231250000001
         
         Pypy with improvements:
-        2.156113
-        2.139545
-        2.413156
-        1.496088
-        4.047559
-        9.551884
-        1.625509
-        3.048558
-        4.867547
-        6.223230
-        0.038463
-        3.637759
-        8.325080
-        5.038974
-        Sum:  54.609465
+        mod by 2:  0.006297
+        mod by 10000:  3.693501
+        mod by 1024 (power of two):  0.011243
+        Div huge number by 2**128: 2.163590
+        rshift: 2.219846
+        lshift: 2.689848
+        Floordiv by 2: 1.460396
+        Floordiv by 3 (not power of two): 4.071267
+        2**10000000: 9.720923
+        (2**N)**100000000 (power of two): 1.639600
+        10000 ** BIGNUM % 100 1.738285
+        i = i * i: 4.861456
+        n**10000 (not power of two): 6.206040
+        Power of two ** power of two: 0.038726
+        v = v * power of two 3.633579
+        v = v * v 8.180117
+        v = v + v 5.006874
+        Sum:  57.341588
 
         A pure python form of those tests where also run
         Improved pypy           | Pypy                  | CPython 2.7.3
@@ -77,6 +80,34 @@
     sumTime += _time
     print "Toom-cook effectivity 100-10000 digits:", _time"""
     
+    V2 = rbigint.fromint(2)
+    num = rbigint.pow(rbigint.fromint(100000000), rbigint.fromint(1024))
+    t = time()
+    for n in xrange(600000):
+        rbigint.mod(num, V2)
+        
+    _time = time() - t
+    sumTime += _time
+    print "mod by 2: ", _time
+    
+    by = rbigint.fromint(10000)
+    t = time()
+    for n in xrange(300000):
+        rbigint.mod(num, by)
+        
+    _time = time() - t
+    sumTime += _time
+    print "mod by 10000: ", _time
+    
+    V1024 = rbigint.fromint(1024)
+    t = time()
+    for n in xrange(300000):
+        rbigint.mod(num, V1024)
+        
+    _time = time() - t
+    sumTime += _time
+    print "mod by 1024 (power of two): ", _time
+    
     t = time()
     num = rbigint.pow(rbigint.fromint(100000000), rbigint.fromint(1024))
     by = rbigint.pow(rbigint.fromint(2), rbigint.fromint(128))
@@ -86,7 +117,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "Div huge number by 2**128:", _time
     
     t = time()
     num = rbigint.fromint(1000000000)
@@ -96,7 +127,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "rshift:", _time
     
     t = time()
     num = rbigint.fromint(1000000000)
@@ -106,18 +137,17 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "lshift:", _time
     
     t = time()
     num = rbigint.fromint(100000000)
-    V2 = rbigint.fromint(2)
     for n in xrange(80000000):
         rbigint.floordiv(num, V2)
         
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "Floordiv by 2:", _time
     
     t = time()
     num = rbigint.fromint(100000000)
@@ -128,7 +158,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "Floordiv by 3 (not power of two):",_time
     
     t = time()
     num = rbigint.fromint(10000000)
@@ -138,7 +168,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "2**10000000:",_time
 
     t = time()
     num = rbigint.fromint(100000000)
@@ -148,7 +178,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "(2**N)**100000000 (power of two):",_time
     
     t = time()
     num = rbigint.pow(rbigint.fromint(10000), rbigint.fromint(2 ** 8))
@@ -160,7 +190,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "10000 ** BIGNUM % 100", _time
     
     t = time()
     i = rbigint.fromint(2**31)
@@ -170,7 +200,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "i = i * i:", _time
     
     t = time()
     
@@ -180,18 +210,16 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "n**10000 (not power of two):",_time
     
     t = time()
-    
-    V1024 = rbigint.fromint(1024)
     for n in xrange(100000):
         rbigint.pow(V1024, V1024)
         
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "Power of two ** power of two:", _time
     
     
     t = time()
@@ -203,7 +231,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "v = v * power of two", _time
     
     t = time()
     v2 = rbigint.fromint(2**8)
@@ -213,7 +241,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "v = v * v", _time
     
     t = time()
     v3 = rbigint.fromint(2**62)
@@ -223,7 +251,7 @@
 
     _time = time() - t
     sumTime += _time
-    print _time
+    print "v = v + v", _time
     
     print "Sum: ", sumTime
     
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to