mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
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:
parent
513a1cd103
commit
4bad9ba282
1 changed files with 13 additions and 18 deletions
|
@ -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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue