From ae9630e51b3f352320863c0a1f5e2dc5a023d1cf Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Wed, 23 Jul 2008 23:02:37 -0700 Subject: [PATCH] Fix speed regression due to PySequence_Fast in for loop. PySequence_Fast isn't so fast after all (due to multiple branching), was a 35% slowdown for looping over lists. Now it handles tuples as well with only about a 4% slowdown to lists compared to before. --- Cython/Compiler/ExprNodes.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 992d922c..92e1e2a7 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1169,20 +1169,24 @@ class NextNode(AtomicExprNode): self.is_temp = 1 def generate_result_code(self, code): - code.putln( - "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())) - 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, - self.iterator.counter.result_code)) - code.putln("} else {") + for py_type in ["List", "Tuple"]: + code.putln( + "if (likely(Py%s_CheckExact(%s))) {" % (py_type, self.iterator.py_result())) + code.putln( + "if (%s >= Py%s_GET_SIZE(%s)) break;" % ( + self.iterator.counter.result_code, + py_type, + self.iterator.py_result())) + code.putln( + "%s = Py%s_GET_ITEM(%s, %s); Py_INCREF(%s); %s++;" % ( + self.result_code, + py_type, + self.iterator.py_result(), + self.iterator.counter.result_code, + self.result_code, + self.iterator.counter.result_code)) + code.put("} else ") + code.putln("{") code.putln( "%s = PyIter_Next(%s);" % ( self.result_code, -- 2.26.2