diff -r bc1a178b3bc8 Objects/longobject.c --- a/Objects/longobject.c Sat Apr 18 05:54:02 2015 +0200 +++ b/Objects/longobject.c Fri May 01 15:51:28 2015 +0200 @@ -15,6 +15,9 @@ #ifndef NSMALLNEGINTS #define NSMALLNEGINTS 5 #endif +#ifndef PyLong_MAXFREELIST +#define PyLong_MAXFREELIST 20 +#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), \ @@ -33,6 +36,11 @@ Py_ssize_t quick_int_allocs, quick_neg_int_allocs; #endif +#if PyLong_MAXFREELIST > 0 +static PyLongObject *free_list[PyLong_MAXFREELIST]; +static int numfree = 0; +#endif + static PyObject * get_small_int(sdigit ival) { @@ -183,6 +191,16 @@ _PyLong_New(Py_ssize_t size) { PyLongObject *result; +#if PyLong_MAXFREELIST > 0 + if (size == 1 && numfree) { + result = free_list[--numfree]; + assert (result != NULL); + assert (Py_TYPE(result) == &PyLong_Type); + /* Inline PyObject_InitVar */ + _Py_NewReference((PyObject *)result); + return result; + } +#endif /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + sizeof(digit)*size. Previous incarnations of this code used sizeof(PyVarObject) instead of the offsetof, but this risks being @@ -2719,6 +2737,12 @@ static void long_dealloc(PyObject *v) { +#if PyLong_MAXFREELIST > 0 + if (numfree < PyLong_MAXFREELIST && Py_TYPE(v) == &PyLong_Type && Py_SIZE(v) == 1) { + free_list[numfree++] = (PyLongObject*)v; + return; + } +#endif Py_TYPE(v)->tp_free(v); } @@ -5110,6 +5134,23 @@ return 1; } +int +PyLong_ClearFreeList(void) +{ +#if PyLong_MAXFREELIST > 0 + PyLongObject *op; + int ret = numfree; + while (numfree) { + op = free_list[--numfree]; + assert(PyLong_CheckExact(op)); + PyObject_Del(op); + } + return ret; +#else + return 0; +#endif +} + void PyLong_Fini(void) { @@ -5124,4 +5165,7 @@ _Py_ForgetReference((PyObject*)v); } #endif +#if PyLong_MAXFREELIST > 0 + (void)PyLong_ClearFreeList(); +#endif }