Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c12da69

Browse files
committed
Huge speedup by inlining some common integer operations:
int+int, int-int, int <compareop> int, and list[int]. (Unfortunately, int*int is way too much code to inline.) Also corrected a NULL that should have been a zero.
1 parent 77eecfa commit c12da69

1 file changed

Lines changed: 75 additions & 5 deletions

File tree

Python/ceval.c

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,22 @@ eval_code2(co, globals, locals,
762762
case BINARY_ADD:
763763
w = POP();
764764
v = POP();
765-
x = PyNumber_Add(v, w);
765+
if (PyInt_Check(v) && PyInt_Check(w)) {
766+
/* INLINE: int + int */
767+
register long a, b, i;
768+
a = ((PyIntObject*) v)->ob_ival;
769+
b = ((PyIntObject*) w)->ob_ival;
770+
i = a + b;
771+
if ((i^a) < 0 && (i^b) < 0) {
772+
PyErr_SetString(PyExc_OverflowError,
773+
"integer addition");
774+
x = NULL;
775+
}
776+
else
777+
x = PyInt_FromLong(i);
778+
}
779+
else
780+
x = PyNumber_Add(v, w);
766781
Py_DECREF(v);
767782
Py_DECREF(w);
768783
PUSH(x);
@@ -772,7 +787,22 @@ eval_code2(co, globals, locals,
772787
case BINARY_SUBTRACT:
773788
w = POP();
774789
v = POP();
775-
x = PyNumber_Subtract(v, w);
790+
if (PyInt_Check(v) && PyInt_Check(w)) {
791+
/* INLINE: int - int */
792+
register long a, b, i;
793+
a = ((PyIntObject*) v)->ob_ival;
794+
b = ((PyIntObject*) w)->ob_ival;
795+
i = a - b;
796+
if ((i^a) < 0 && (i^~b) < 0) {
797+
PyErr_SetString(PyExc_OverflowError,
798+
"integer subtraction");
799+
x = NULL;
800+
}
801+
else
802+
x = PyInt_FromLong(i);
803+
}
804+
else
805+
x = PyNumber_Subtract(v, w);
776806
Py_DECREF(v);
777807
Py_DECREF(w);
778808
PUSH(x);
@@ -782,7 +812,24 @@ eval_code2(co, globals, locals,
782812
case BINARY_SUBSCR:
783813
w = POP();
784814
v = POP();
785-
x = PyObject_GetItem(v, w);
815+
if (PyList_Check(v) && PyInt_Check(w)) {
816+
/* INLINE: list[int] */
817+
long i = PyInt_AsLong(w);
818+
if (i < 0)
819+
i += ((PyListObject*) v)->ob_size;
820+
if (i < 0 ||
821+
i >= ((PyListObject*) v)->ob_size) {
822+
PyErr_SetString(PyExc_IndexError,
823+
"list index out of range");
824+
x = NULL;
825+
}
826+
else {
827+
x = ((PyListObject*) v)->ob_item[i];
828+
Py_INCREF(x);
829+
}
830+
}
831+
else
832+
x = PyObject_GetItem(v, w);
786833
Py_DECREF(v);
787834
Py_DECREF(w);
788835
PUSH(x);
@@ -934,7 +981,7 @@ eval_code2(co, globals, locals,
934981
f->f_builtins, "_", v)) == 0 &&
935982
!Py_SuppressPrintingFlag) {
936983
err = Py_FlushLine();
937-
if (err == NULL) {
984+
if (err == 0) {
938985
x = PySys_GetObject("stdout");
939986
if (x == NULL)
940987
err = -1;
@@ -1287,7 +1334,30 @@ eval_code2(co, globals, locals,
12871334
case COMPARE_OP:
12881335
w = POP();
12891336
v = POP();
1290-
x = cmp_outcome(oparg, v, w);
1337+
if (PyInt_Check(v) && PyInt_Check(w)) {
1338+
/* INLINE: cmp(int, int) */
1339+
register long a, b;
1340+
register int res;
1341+
a = ((PyIntObject*) v)->ob_ival;
1342+
b = ((PyIntObject*) w)->ob_ival;
1343+
switch (oparg) {
1344+
case LT: res = a < b; break;
1345+
case LE: res = a <= b; break;
1346+
case EQ: res = a == b; break;
1347+
case NE: res = a != b; break;
1348+
case GT: res = a > b; break;
1349+
case GE: res = a >= b; break;
1350+
case IS: res = v == w; break;
1351+
case IS_NOT: res = v != w; break;
1352+
default: goto slow_compare;
1353+
}
1354+
x = res ? Py_True : Py_False;
1355+
Py_INCREF(x);
1356+
}
1357+
else {
1358+
slow_compare:
1359+
x = cmp_outcome(oparg, v, w);
1360+
}
12911361
Py_DECREF(v);
12921362
Py_DECREF(w);
12931363
PUSH(x);

0 commit comments

Comments
 (0)