From 4bad9ba2827a3cac04b2cffaf0825224b7dc3c55 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 19 Jan 2003 05:08:13 +0000 Subject: SF patch #670367: Micro-optimizations for ceval.c Make the code slightly shorter, faster, and easier to read. * Eliminate unused DUP_TOPX code for x==1. compile.c always generates DUP_TOP instead. * Since only two cases remain for DUP_TOPX, replace the switch-case with if-elseif. * The in-lined integer compare does a CheckExact on both arguments. Since the second is a little more likely to fail, test it first. * The switch-case for IS/IS_NOT and IN/NOT_IN can separate the regular and inverted cases with no additional work. For all four paths, saves a test and jump. --- Python/ceval.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 1fab1cc..8547f85 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -855,14 +855,7 @@ eval_frame(PyFrameObject *f) continue; case DUP_TOPX: - switch (oparg) { - case 1: - x = TOP(); - Py_INCREF(x); - STACKADJ(1); - SET_TOP(x); - continue; - case 2: + if (oparg == 2) { x = TOP(); Py_INCREF(x); w = SECOND(); @@ -871,7 +864,7 @@ eval_frame(PyFrameObject *f) SET_TOP(x); SET_SECOND(w); continue; - case 3: + } else if (oparg == 3) { x = TOP(); Py_INCREF(x); w = SECOND(); @@ -883,10 +876,9 @@ eval_frame(PyFrameObject *f) SET_SECOND(w); SET_THIRD(v); continue; - default: - Py_FatalError("invalid argument to DUP_TOPX" - " (bytecode corruption?)"); } + Py_FatalError("invalid argument to DUP_TOPX" + " (bytecode corruption?)"); break; case UNARY_POSITIVE: @@ -1842,7 +1834,7 @@ eval_frame(PyFrameObject *f) case COMPARE_OP: w = POP(); v = TOP(); - if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { + if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) { /* INLINE: cmp(int, int) */ register long a, b; register int res; @@ -3581,18 +3573,21 @@ cmp_outcome(int op, register PyObject *v, register PyObject *w) int res = 0; switch (op) { case PyCmp_IS: - case PyCmp_IS_NOT: res = (v == w); - if (op == (int) PyCmp_IS_NOT) - res = !res; + break; + case PyCmp_IS_NOT: + res = (v != w); break; case PyCmp_IN: + res = PySequence_Contains(w, v); + if (res < 0) + return NULL; + break; case PyCmp_NOT_IN: res = PySequence_Contains(w, v); if (res < 0) return NULL; - if (op == (int) PyCmp_NOT_IN) - res = !res; + res = !res; break; case PyCmp_EXC_MATCH: res = PyErr_GivenExceptionMatches(v, w); -- cgit v0.12