more readable for-loop code, optimise tuples the way lists are optimised (basically...
authorStefan Behnel <scoder@users.berlios.de>
Fri, 11 Jul 2008 12:45:25 +0000 (14:45 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Fri, 11 Jul 2008 12:45:25 +0000 (14:45 +0200)
Cython/Compiler/ExprNodes.py
tests/run/r_forloop.pyx

index ed770ef71bcfd9e4c15698ac051b9757b6caa42b..5329de73afe21e92226cfdc9eeea1d033d399fdd 100644 (file)
@@ -1145,16 +1145,22 @@ class IteratorNode(ExprNode):
     
     def generate_result_code(self, code):
         code.putln(
-            "if (PyList_CheckExact(%s)) { %s = 0; %s = %s; Py_INCREF(%s); }" % (
+            "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
                 self.sequence.py_result(),
+                self.sequence.py_result()))
+        code.putln(
+            "%s = 0; %s = %s; Py_INCREF(%s);" % (
                 self.counter.result_code,
                 self.result_code,
                 self.sequence.py_result(),
                 self.result_code))
-        code.putln("else { %s = PyObject_GetIter(%s); %s }" % (
+        code.putln("} else {")
+        code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
+                self.counter.result_code,
                 self.result_code,
                 self.sequence.py_result(),
                 code.error_goto_if_null(self.result_code, self.pos)))
+        code.putln("}")
 
 
 class NextNode(AtomicExprNode):
@@ -1173,15 +1179,19 @@ class NextNode(AtomicExprNode):
     
     def generate_result_code(self, code):
         code.putln(
-            "if (PyList_CheckExact(%s)) { if (%s >= PyList_GET_SIZE(%s)) break; %s = PyList_GET_ITEM(%s, %s++); Py_INCREF(%s); }" % (
-                self.iterator.py_result(),
+            "if (likely(%s != -1)) {" % self.iterator.counter.result_code)
+        code.putln(
+            "if (%s >= PySequence_Fast_GET_SIZE(%s)) break;" % (
                 self.iterator.counter.result_code,
-                self.iterator.py_result(),
+                self.iterator.py_result()))
+        code.putln(
+            "%s = PySequence_Fast_GET_ITEM(%s, %s); Py_INCREF(%s); %s++;" % (
                 self.result_code,
                 self.iterator.py_result(),
                 self.iterator.counter.result_code,
-                self.result_code))
-        code.putln("else {")
+                self.result_code,
+                self.iterator.counter.result_code))
+        code.putln("} else {")
         code.putln(
             "%s = PyIter_Next(%s);" % (
                 self.result_code,
index 4dc7b3767dd7a16e7febd517511fbdf7b5e7f78e..81bfab73a51c9ed54ab85c7b96742157e5c899a8 100644 (file)
@@ -1,5 +1,12 @@
 __doc__ = u"""
-  >>> go()
+  >>> go_py()
+  Spam!
+  Spam!
+  Spam!
+  Spam!
+  Spam!
+
+  >>> go_c()
   Spam!
   Spam!
   Spam!
@@ -7,7 +14,11 @@ __doc__ = u"""
   Spam!
 """
 
-def go():
+def go_py():
     for i in range(5):
         print u"Spam!"
 
+def go_c():
+    cdef int i
+    for i in range(5):
+        print u"Spam!"