From 8d73ea74d1e32c8ad39974871e886de9b95f3b9c Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Thu, 20 Aug 2009 22:19:58 +0200 Subject: [PATCH] safe a few cycles (~4%) when calling 'in' on dicts --- Cython/Compiler/ExprNodes.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index bd35c026..c291431c 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -4827,14 +4827,31 @@ class CmpNode(object): if 'not' in op: negation = "!" else: negation = "" if op == 'in' or op == 'not_in': - code.putln( - "%s = %s(%sPySequence_Contains(%s, %s)); %s" % ( - result_code, - coerce_result, - negation, - operand2.py_result(), - operand1.py_result(), - code.error_goto_if_neg(result_code, self.pos))) + if operand2.type is dict_type: + code.globalstate.use_utility_code( + raise_none_iter_error_utility_code) + code.putln("if (unlikely(%s == Py_None)) {" % operand2.py_result()) + code.putln("__Pyx_RaiseNoneNotIterableError(); %s" % + code.error_goto(self.pos)) + code.putln("} else {") + code.putln( + "%s = %s(%sPyDict_Contains(%s, %s)); %s" % ( + result_code, + coerce_result, + negation, + operand2.py_result(), + operand1.py_result(), + code.error_goto_if_neg(result_code, self.pos))) + code.putln("}") + else: + code.putln( + "%s = %s(%sPySequence_Contains(%s, %s)); %s" % ( + result_code, + coerce_result, + negation, + operand2.py_result(), + operand1.py_result(), + code.error_goto_if_neg(result_code, self.pos))) elif (operand1.type.is_pyobject and op not in ('is', 'is_not')): code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % ( -- 2.26.2