[pypy-svn] r52681 - in pypy/dist/pypy/rlib: . test

arigo at codespeak.net arigo at codespeak.net
Tue Mar 18 12:15:43 CET 2008


Author: arigo
Date: Tue Mar 18 12:15:43 2008
New Revision: 52681

Modified:
   pypy/dist/pypy/rlib/rope.py
   pypy/dist/pypy/rlib/test/test_rope.py
Log:
Replace masked_power() with masked_mul_by_1000003_pow().  As we know
that we only do powers of 1000003, we can write a simpler algo that only
needs half as many multiplications.


Modified: pypy/dist/pypy/rlib/rope.py
==============================================================================
--- pypy/dist/pypy/rlib/rope.py	(original)
+++ pypy/dist/pypy/rlib/rope.py	Tue Mar 18 12:15:43 2008
@@ -1,6 +1,7 @@
 import py
 import sys
 from pypy.rlib.rarithmetic import intmask, _hash_string, ovfcheck
+from pypy.rlib.rarithmetic import r_uint, LONG_BIT
 from pypy.rlib.objectmodel import we_are_translated
 import math
 
@@ -25,30 +26,19 @@
         a, b = b, a + b
         i += 1
 
-def masked_power(a, b):
-    if b == 0:
-        return 1
-    if b == 1:
-        return a
-    if a == 0:
-        return 0
-    if a == 1:
-        return 1
-    num_bits = 2
-    mask = b >> 2
-    while mask:
-        num_bits += 1
-        mask >>= 1
-    result = a
-    mask = 1 << (num_bits - 2)
-    #import pdb; pdb.set_trace()
-    for i in range(num_bits - 1):
-        if mask & b:
-            result = intmask(result * result * a)
-        else:
-            result = intmask(result * result)
-        mask >>= 1
-    return result
+mul_by_1000003_pow_table = [intmask(pow(1000003, 2**_i, 2**LONG_BIT))
+                            for _i in range(LONG_BIT)]
+
+def masked_mul_by_1000003_pow(a, b):
+    """Computes intmask(a * (1000003**b))."""
+    index = 0
+    b = r_uint(b)
+    while b:
+        if b & 1:
+            a = intmask(a * mul_by_1000003_pow_table[index])
+        b >>= 1
+        index += 1
+    return a
 
 
 class GlobalRopeInfo(object):
@@ -65,7 +55,7 @@
         result.charbitmask = self.charbitmask | other.charbitmask
         h1 = self.hash
         h2 = other.hash
-        x = intmask(h2 + h1 * (masked_power(1000003, rightlength)))
+        x = intmask(h2 + masked_mul_by_1000003_pow(h1, rightlength))
         x |= HIGHEST_BIT_SET
         result.hash = x
         result.is_ascii = self.is_ascii and other.is_ascii

Modified: pypy/dist/pypy/rlib/test/test_rope.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_rope.py	(original)
+++ pypy/dist/pypy/rlib/test/test_rope.py	Tue Mar 18 12:15:43 2008
@@ -686,7 +686,7 @@
     for i in range(0, 60, 13):
         print i
         for j in range(1, 10000, 7):
-            assert intmask(i ** j) == masked_power(i, j)
+            assert intmask(i * (1000003**j)) == masked_mul_by_1000003_pow(i, j)
 
 
 def test_seekable_bug():



More information about the Pypy-commit mailing list