diff -r f6a89f6cadd0 Include/longintrepr.h --- a/Include/longintrepr.h Fri Feb 05 18:26:20 2016 -0500 +++ b/Include/longintrepr.h Sat Feb 06 02:43:45 2016 +0100 @@ -96,6 +96,13 @@ PyAPI_FUNC(PyLongObject *) _PyLong_New(P /* Return a copy of src. */ PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); +/* convert a PyLong of size 1, 0 or -1 to an sdigit */ +#define PYLONG_MEDIUM_VALUE(x) \ + (assert(-1 <= Py_SIZE(x) && Py_SIZE(x) <= 1), \ + Py_SIZE(x) < 0 ? -(sdigit)((PyLongObject*)(x))->ob_digit[0] : \ + (Py_SIZE(x) == 0 ? (sdigit)0 : \ + (sdigit)((PyLongObject*)(x))->ob_digit[0])) + #ifdef __cplusplus } #endif diff -r f6a89f6cadd0 Objects/longobject.c --- a/Objects/longobject.c Fri Feb 05 18:26:20 2016 -0500 +++ b/Objects/longobject.c Sat Feb 06 02:43:45 2016 +0100 @@ -16,11 +16,7 @@ #define NSMALLNEGINTS 5 #endif -/* convert a PyLong of size 1, 0 or -1 to an sdigit */ -#define MEDIUM_VALUE(x) (assert(-1 <= Py_SIZE(x) && Py_SIZE(x) <= 1), \ - Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ - (Py_SIZE(x) == 0 ? (sdigit)0 : \ - (sdigit)(x)->ob_digit[0])) +#define MEDIUM_VALUE(x) PYLONG_MEDIUM_VALUE(x) #if NSMALLNEGINTS + NSMALLPOSINTS > 0 /* Small integers are preallocated in this array so that they diff -r f6a89f6cadd0 Python/ceval.c --- a/Python/ceval.c Fri Feb 05 18:26:20 2016 -0500 +++ b/Python/ceval.c Sat Feb 06 02:43:45 2016 +0100 @@ -1560,7 +1560,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; - if (PyUnicode_CheckExact(left) && + if (PyLong_CheckExact(left) && Py_ABS(Py_SIZE(left)) <= 1 + && PyLong_CheckExact(right) && Py_ABS(Py_SIZE(right)) <= 1) + { + sum = PyLong_FromLong(PYLONG_MEDIUM_VALUE(left) + + PYLONG_MEDIUM_VALUE(right)); + Py_DECREF(left); + } + else if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { sum = unicode_concatenate(left, right, f, next_instr); /* unicode_concatenate consumed the ref to v */ @@ -1579,7 +1586,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int TARGET(BINARY_SUBTRACT) { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *diff = PyNumber_Subtract(left, right); + PyObject *diff; + if (PyLong_CheckExact(left) && Py_ABS(Py_SIZE(left)) <= 1 + && PyLong_CheckExact(right) && Py_ABS(Py_SIZE(right)) <= 1) + { + diff = PyLong_FromLong(PYLONG_MEDIUM_VALUE(left) + - PYLONG_MEDIUM_VALUE(right)); + } + else { + diff = PyNumber_Subtract(left, right); + } Py_DECREF(right); Py_DECREF(left); SET_TOP(diff); @@ -1591,7 +1607,23 @@ PyEval_EvalFrameEx(PyFrameObject *f, int TARGET(BINARY_SUBSCR) { PyObject *sub = POP(); PyObject *container = TOP(); - PyObject *res = PyObject_GetItem(container, sub); + int slow_path = 1; + PyObject *res; + + if (PyList_CheckExact(container) && PyLong_CheckExact(sub)) { + /* INLINE: list[int] */ + Py_ssize_t i = PyLong_AsSsize_t(sub); + if (i < 0) + i += PyList_GET_SIZE(container); + if (i >= 0 && i < PyList_GET_SIZE(container)) { + res = PyList_GET_ITEM(container, i); + Py_INCREF(res); + slow_path = 0; + } + } + + if (slow_path) + res = PyObject_GetItem(container, sub); Py_DECREF(container); Py_DECREF(sub); SET_TOP(res); @@ -1760,7 +1792,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; - if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { + if (PyLong_CheckExact(left) && Py_ABS(Py_SIZE(left)) <= 1 + && PyLong_CheckExact(right) && Py_ABS(Py_SIZE(right)) <= 1) + { + sum = PyLong_FromLong(PYLONG_MEDIUM_VALUE(left) + + PYLONG_MEDIUM_VALUE(right)); + Py_DECREF(left); + } + else if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { sum = unicode_concatenate(left, right, f, next_instr); /* unicode_concatenate consumed the ref to v */ } @@ -1778,7 +1817,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int TARGET(INPLACE_SUBTRACT) { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *diff = PyNumber_InPlaceSubtract(left, right); + PyObject *diff; + if (PyLong_CheckExact(left) && Py_ABS(Py_SIZE(left)) <= 1 + && PyLong_CheckExact(right) && Py_ABS(Py_SIZE(right)) <= 1) + { + diff = PyLong_FromLong(PYLONG_MEDIUM_VALUE(left) + - PYLONG_MEDIUM_VALUE(right)); + } + else { + diff = PyNumber_InPlaceSubtract(left, right); + } Py_DECREF(left); Py_DECREF(right); SET_TOP(diff);