diff -r 5f2ae82157af Objects/longobject.c --- a/Objects/longobject.c Wed May 06 19:22:55 2015 +0300 +++ b/Objects/longobject.c Wed May 06 20:24:01 2015 +0300 @@ -179,6 +179,10 @@ PyLongObject * #define MAX_LONG_DIGITS \ ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) +#define PyLong_MAXFREELIST 100 +static PyLongObject *free_list = NULL; +static int numfree = 0; + PyLongObject * _PyLong_New(Py_ssize_t size) { @@ -193,11 +197,18 @@ PyLongObject * "too many digits in integer"); return NULL; } - result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + - size*sizeof(digit)); - if (!result) { - PyErr_NoMemory(); - return NULL; + if (size == 1 && free_list != NULL) { + result = free_list; + free_list = (PyLongObject *)Py_TYPE(free_list); + numfree--; + } + else { + result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + + size*sizeof(digit)); + if (!result) { + PyErr_NoMemory(); + return NULL; + } } return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); } @@ -249,7 +260,7 @@ PyLong_FromLong(long ival) } /* Fast path for single-digit ints */ - if (!(abs_ival >> PyLong_SHIFT)) { + if (abs_ival < (1UL << PyLong_SHIFT)) { v = _PyLong_New(1); if (v) { Py_SIZE(v) = sign; @@ -261,7 +272,7 @@ PyLong_FromLong(long ival) #if PyLong_SHIFT==15 /* 2 digits */ - if (!(abs_ival >> 2*PyLong_SHIFT)) { + if (abs_ival < (1UL << 2*PyLong_SHIFT)) { v = _PyLong_New(2); if (v) { Py_SIZE(v) = 2*sign; @@ -2719,7 +2730,16 @@ PyLong_AsDouble(PyObject *v) static void long_dealloc(PyObject *v) { - Py_TYPE(v)->tp_free(v); + Py_ssize_t size = Py_SIZE(v); + if ((size == 1 || size == -1) && + numfree < PyLong_MAXFREELIST && + Py_TYPE(v) == &PyLong_Type) { + Py_TYPE(v) = (PyTypeObject *)free_list; + free_list = (PyLongObject *)v; + numfree++; + } + else + Py_TYPE(v)->tp_free(v); } static int