From: Stefan Behnel Date: Fri, 11 Jul 2008 12:45:25 +0000 (+0200) Subject: more readable for-loop code, optimise tuples the way lists are optimised (basically... X-Git-Tag: 0.9.8.1~123^2~22 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=3e431781302094df4401ccd49975fd70dace3871;p=cython.git more readable for-loop code, optimise tuples the way lists are optimised (basically no overhead) --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index ed770ef7..5329de73 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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, diff --git a/tests/run/r_forloop.pyx b/tests/run/r_forloop.pyx index 4dc7b376..81bfab73 100644 --- a/tests/run/r_forloop.pyx +++ b/tests/run/r_forloop.pyx @@ -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!"