[pypy-svn] r68129 - in pypy/trunk/pypy/rpython: . test

arigo at codespeak.net arigo at codespeak.net
Fri Oct 2 16:37:19 CEST 2009


Author: arigo
Date: Fri Oct  2 16:37:19 2009
New Revision: 68129

Modified:
   pypy/trunk/pypy/rpython/rrange.py
   pypy/trunk/pypy/rpython/test/test_rrange.py
Log:
Small performance improvement for len(range(1-or-2-arguments)).
Don't call the general 3-arguments version of ll_rangelen() in that case.


Modified: pypy/trunk/pypy/rpython/rrange.py
==============================================================================
--- pypy/trunk/pypy/rpython/rrange.py	(original)
+++ pypy/trunk/pypy/rpython/rrange.py	Fri Oct  2 16:37:19 2009
@@ -20,11 +20,13 @@
 
     def rtype_len(self, hop):
         v_rng, = hop.inputargs(self)
-        if self.step != 0:
-            cstep = hop.inputconst(Signed, self.step)
+        if self.step == 1:
+            return hop.gendirectcall(ll_rangelen1, v_rng)
+        elif self.step != 0:
+            v_step = hop.inputconst(Signed, self.step)
         else:
-            cstep = self._getstep(v_rng, hop)
-        return hop.gendirectcall(ll_rangelen, v_rng, cstep)
+            v_step = self._getstep(v_rng, hop)
+        return hop.gendirectcall(ll_rangelen, v_rng, v_step)
 
 class __extend__(pairtype(AbstractRangeRepr, IntegerRepr)):
 
@@ -62,6 +64,12 @@
 def ll_rangelen(l, step):
     return _ll_rangelen(l.start, l.stop, step)
 
+def ll_rangelen1(l):
+    result = l.stop - l.start
+    if result < 0:
+        result = 0
+    return result
+
 def ll_rangeitem_nonneg(func, l, index, step):
     if func is dum_checkidx and index >= _ll_rangelen(l.start, l.stop, step):
         raise IndexError

Modified: pypy/trunk/pypy/rpython/test/test_rrange.py
==============================================================================
--- pypy/trunk/pypy/rpython/test/test_rrange.py	(original)
+++ pypy/trunk/pypy/rpython/test/test_rrange.py	Fri Oct  2 16:37:19 2009
@@ -67,13 +67,38 @@
         res = self.interpret(dummyfn, [10])
         assert res == 45
 
-    def test_range_len(self):
+    def test_range_len_nostep(self):
         def dummyfn(start, stop):
             r = range(start, stop)
             return len(r)
         start, stop = 10, 17
         res = self.interpret(dummyfn, [start, stop])
         assert res == dummyfn(start, stop)
+        start, stop = 17, 10
+        res = self.interpret(dummyfn, [start, stop])
+        assert res == 0
+
+    def test_range_len_step_const(self):
+        def dummyfn(start, stop):
+            r = range(start, stop, -2)
+            return len(r)
+        start, stop = 10, 17
+        res = self.interpret(dummyfn, [start, stop])
+        assert res == 0
+        start, stop = 17, 10
+        res = self.interpret(dummyfn, [start, stop])
+        assert res == dummyfn(start, stop)
+
+    def test_range_len_step_nonconst(self):
+        def dummyfn(start, stop, step):
+            r = range(start, stop, step)
+            return len(r)
+        start, stop, step = 10, 17, -3
+        res = self.interpret(dummyfn, [start, stop, step])
+        assert res == 0
+        start, stop, step = 17, 10, -3
+        res = self.interpret(dummyfn, [start, stop, step])
+        assert res == dummyfn(start, stop, step)
 
     def test_range2list(self):
         def dummyfn(start, stop):



More information about the Pypy-commit mailing list