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.
This commit is contained in:
Raymond Hettinger 2003-01-19 05:08:13 +00:00
parent 513a1cd103
commit 4bad9ba282

View file

@ -855,14 +855,7 @@ eval_frame(PyFrameObject *f)
continue; continue;
case DUP_TOPX: case DUP_TOPX:
switch (oparg) { if (oparg == 2) {
case 1:
x = TOP();
Py_INCREF(x);
STACKADJ(1);
SET_TOP(x);
continue;
case 2:
x = TOP(); x = TOP();
Py_INCREF(x); Py_INCREF(x);
w = SECOND(); w = SECOND();
@ -871,7 +864,7 @@ eval_frame(PyFrameObject *f)
SET_TOP(x); SET_TOP(x);
SET_SECOND(w); SET_SECOND(w);
continue; continue;
case 3: } else if (oparg == 3) {
x = TOP(); x = TOP();
Py_INCREF(x); Py_INCREF(x);
w = SECOND(); w = SECOND();
@ -883,10 +876,9 @@ eval_frame(PyFrameObject *f)
SET_SECOND(w); SET_SECOND(w);
SET_THIRD(v); SET_THIRD(v);
continue; continue;
default: }
Py_FatalError("invalid argument to DUP_TOPX" Py_FatalError("invalid argument to DUP_TOPX"
" (bytecode corruption?)"); " (bytecode corruption?)");
}
break; break;
case UNARY_POSITIVE: case UNARY_POSITIVE:
@ -1842,7 +1834,7 @@ eval_frame(PyFrameObject *f)
case COMPARE_OP: case COMPARE_OP:
w = POP(); w = POP();
v = TOP(); v = TOP();
if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
/* INLINE: cmp(int, int) */ /* INLINE: cmp(int, int) */
register long a, b; register long a, b;
register int res; register int res;
@ -3581,17 +3573,20 @@ cmp_outcome(int op, register PyObject *v, register PyObject *w)
int res = 0; int res = 0;
switch (op) { switch (op) {
case PyCmp_IS: case PyCmp_IS:
case PyCmp_IS_NOT:
res = (v == w); res = (v == w);
if (op == (int) PyCmp_IS_NOT) break;
res = !res; case PyCmp_IS_NOT:
res = (v != w);
break; break;
case PyCmp_IN: case PyCmp_IN:
res = PySequence_Contains(w, v);
if (res < 0)
return NULL;
break;
case PyCmp_NOT_IN: case PyCmp_NOT_IN:
res = PySequence_Contains(w, v); res = PySequence_Contains(w, v);
if (res < 0) if (res < 0)
return NULL; return NULL;
if (op == (int) PyCmp_NOT_IN)
res = !res; res = !res;
break; break;
case PyCmp_EXC_MATCH: case PyCmp_EXC_MATCH: