[pypy-commit] pypy math-improvements: Prebuild nulldigits list for use on null results where the list is not modified, reorder if operations in int_mul so power of two happens before single size check

stian pypy.commits at gmail.com
Thu Oct 19 19:18:21 EDT 2017


Author: stian
Branch: math-improvements
Changeset: r92805:587f1f780bd1
Date: 2017-10-19 23:43 +0200
http://bitbucket.org/pypy/pypy/changeset/587f1f780bd1/

Log:	Prebuild nulldigits list for use on null results where the list is
	not modified, reorder if operations in int_mul so power of two
	happens before single size check

diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -108,6 +108,7 @@
 
 NULLDIGIT = _store_digit(0)
 ONEDIGIT = _store_digit(1)
+NULLDIGITS = [NULLDIGIT]
 
 def _check_digits(l):
     for x in l:
@@ -139,7 +140,7 @@
     _immutable_ = True
     _immutable_fields_ = ["_digits"]
 
-    def __init__(self, digits=[NULLDIGIT], sign=0, size=0):
+    def __init__(self, digits=NULLDIGITS, sign=0, size=0):
         if not we_are_translated():
             _check_digits(digits)
         make_sure_not_resized(digits)
@@ -742,9 +743,13 @@
         bsign = -1 if b < 0 else 1
 
         if digit == 1:
-            if self.sign == bsign:
+            if bsign == 1:
                 return self
-            return rbigint(self._digits[:self.numdigits()], self.sign * bsign, asize)
+            return rbigint(self._digits[:asize], self.sign * bsign, asize)
+        elif digit & (digit - 1) == 0:
+            result = self.lqshift(ptwotable[digit])
+        elif digit == 10:
+            result = self.lqshift(3).add(self.lqshift(1))
         elif asize == 1:
             res = self.widedigit(0) * digit
             carry = res >> SHIFT
@@ -752,9 +757,6 @@
                 return rbigint([_store_digit(res & MASK), _store_digit(carry)], self.sign * bsign, 2)
             else:
                 return rbigint([_store_digit(res & MASK)], self.sign * bsign, 1)
-
-        elif digit & (digit - 1) == 0:
-            result = self.lqshift(ptwotable[digit])
         else:
             result = _muladd1(self, digit)
 
@@ -1395,7 +1397,7 @@
             self.size = i
         if self.numdigits() == 1 and self._digits[0] == NULLDIGIT:
             self.sign = 0
-            self._digits = [NULLDIGIT]
+            self._digits = NULLDIGITS
 
     _normalize._always_inline_ = True
 
@@ -1486,7 +1488,7 @@
     if x > 0:
         return digits_from_nonneg_long(x), 1
     elif x == 0:
-        return [NULLDIGIT], 0
+        return NULLDIGITS, 0
     elif x != most_neg_value_of_same_type(x):
         # normal case
         return digits_from_nonneg_long(-x), -1
@@ -1504,7 +1506,7 @@
 def args_from_long(x):
     if x >= 0:
         if x == 0:
-            return [NULLDIGIT], 0
+            return NULLDIGITS, 0
         else:
             return digits_from_nonneg_long(x), 1
     else:
@@ -1766,8 +1768,8 @@
     size_lo = min(size_n, size)
 
     # We use "or" her to avoid having a check where list can be empty in _normalize.
-    lo = rbigint(n._digits[:size_lo] or [NULLDIGIT], 1)
-    hi = rbigint(n._digits[size_lo:n.size] or [NULLDIGIT], 1)
+    lo = rbigint(n._digits[:size_lo] or NULLDIGITS, 1)
+    hi = rbigint(n._digits[size_lo:n.size] or NULLDIGITS, 1)
     lo._normalize()
     hi._normalize()
     return hi, lo
diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py
--- a/rpython/rlib/test/test_rbigint.py
+++ b/rpython/rlib/test/test_rbigint.py
@@ -28,8 +28,8 @@
 
 class TestRLong(object):
     def test_simple(self):
-        for op1 in [-2, -1, 0, 1, 2, 50]:
-            for op2 in [-2, -1, 0, 1, 2, 50]:
+        for op1 in [-2, -1, 0, 1, 2, 10, 50]:
+            for op2 in [-2, -1, 0, 1, 2, 10, 50]:
                 rl_op1 = rbigint.fromint(op1)
                 rl_op2 = rbigint.fromint(op2)
                 for op in "add sub mul".split():


More information about the pypy-commit mailing list