diff -r 6f0e49ed0589 Objects/dictobject.c --- a/Objects/dictobject.c Wed Nov 14 11:19:42 2012 +0000 +++ b/Objects/dictobject.c Wed Nov 14 15:10:29 2012 +0200 @@ -242,6 +242,12 @@ static PyDictObject *free_list[PyDict_MAXFREELIST]; static int numfree = 0; +#ifndef PyDict_MAXFREEKEYLIST +#define PyDict_MAXFREEKEYLIST PyDict_MAXFREELIST +#endif +static PyDictKeysObject *free_key_list[PyDict_MAXFREEKEYLIST]; +static int numfree_key = 0; + int PyDict_ClearFreeList(void) { @@ -252,6 +258,12 @@ assert(PyDict_CheckExact(op)); PyObject_GC_Del(op); } + ret += numfree_key; + while (numfree_key) { + PyDictKeysObject *keys = free_key_list[--numfree_key]; + assert(DK_SIZE(keys) == PyDict_MINSIZE_COMBINED); + PyMem_FREE(keys); + } return ret; } @@ -261,6 +273,10 @@ { _PyDebugAllocatorStats(out, "free PyDictObject", numfree, sizeof(PyDictObject)); + _PyDebugAllocatorStats(out, + "free PyDictKeysObject", numfree_key, + sizeof(PyDictKeysObject) + + sizeof(PyDictKeyEntry)*(PyDict_MINSIZE_COMBINED-1)); } @@ -344,11 +360,17 @@ assert(size >= PyDict_MINSIZE_SPLIT); assert(IS_POWER_OF_2(size)); - dk = PyMem_MALLOC(sizeof(PyDictKeysObject) + - sizeof(PyDictKeyEntry) * (size-1)); - if (dk == NULL) { - PyErr_NoMemory(); - return NULL; + if (size == PyDict_MINSIZE_COMBINED && numfree_key) { + dk = free_key_list[--numfree_key]; + assert (dk != NULL); + } + else { + dk = PyMem_MALLOC(sizeof(PyDictKeysObject) + + sizeof(PyDictKeyEntry) * (size-1)); + if (dk == NULL) { + PyErr_NoMemory(); + return NULL; + } } DK_DEBUG_INCREF dk->dk_refcnt = 1; dk->dk_size = size; @@ -373,7 +395,10 @@ Py_XDECREF(entries[i].me_key); Py_XDECREF(entries[i].me_value); } - PyMem_FREE(keys); + if (n == PyDict_MINSIZE_COMBINED && numfree_key < PyDict_MAXFREEKEYLIST) + free_key_list[numfree_key++] = keys; + else + PyMem_FREE(keys); } #define new_values(size) PyMem_NEW(PyObject *, size)