Remove the freelist scheme for setobjects.

The setobject freelist was consuming memory but not providing much value.
Even when a freelisted setobject was available, most of the setobject
fields still needed to be initialized and the small table still required
a memset().  This meant that the custom freelisting scheme for sets was
providing almost no incremental benefit over the default Python freelist
scheme used by _PyObject_Malloc() in Objects/obmalloc.c.
This commit is contained in:
Raymond Hettinger 2013-09-07 20:26:50 -07:00
parent ff6382b40d
commit 8f8839e10a
3 changed files with 8 additions and 49 deletions

View File

@ -105,7 +105,6 @@ PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
PyAPI_FUNC(int) PySet_ClearFreeList(void); PyAPI_FUNC(int) PySet_ClearFreeList(void);
PyAPI_FUNC(void) _PySet_DebugMallocStats(FILE *out);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1955,7 +1955,6 @@ _PyObject_DebugTypeStats(FILE *out)
_PyFrame_DebugMallocStats(out); _PyFrame_DebugMallocStats(out);
_PyList_DebugMallocStats(out); _PyList_DebugMallocStats(out);
_PyMethod_DebugMallocStats(out); _PyMethod_DebugMallocStats(out);
_PySet_DebugMallocStats(out);
_PyTuple_DebugMallocStats(out); _PyTuple_DebugMallocStats(out);
} }

View File

@ -57,13 +57,6 @@ PyObject *_PySet_Dummy = dummy;
INIT_NONZERO_SET_SLOTS(so); \ INIT_NONZERO_SET_SLOTS(so); \
} while(0) } while(0)
/* Reuse scheme to save calls to malloc, free, and memset */
#ifndef PySet_MAXFREELIST
#define PySet_MAXFREELIST 80
#endif
static PySetObject *free_list[PySet_MAXFREELIST];
static int numfree = 0;
/* ======================================================================== */ /* ======================================================================== */
/* ======= Begin logic for probing the hash table ========================= */ /* ======= Begin logic for probing the hash table ========================= */
@ -565,10 +558,7 @@ set_dealloc(PySetObject *so)
} }
if (so->table != so->smalltable) if (so->table != so->smalltable)
PyMem_DEL(so->table); PyMem_DEL(so->table);
if (numfree < PySet_MAXFREELIST && PyAnySet_CheckExact(so)) Py_TYPE(so)->tp_free(so);
free_list[numfree++] = so;
else
Py_TYPE(so)->tp_free(so);
Py_TRASHCAN_SAFE_END(so) Py_TRASHCAN_SAFE_END(so)
} }
@ -1023,22 +1013,12 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
PySetObject *so = NULL; PySetObject *so = NULL;
/* create PySetObject structure */ /* create PySetObject structure */
if (numfree && so = (PySetObject *)type->tp_alloc(type, 0);
(type == &PySet_Type || type == &PyFrozenSet_Type)) { if (so == NULL)
so = free_list[--numfree]; return NULL;
assert (so != NULL && PyAnySet_CheckExact(so)); /* tp_alloc has already zeroed the structure */
Py_TYPE(so) = type; assert(so->table == NULL && so->fill == 0 && so->used == 0);
_Py_NewReference((PyObject *)so); INIT_NONZERO_SET_SLOTS(so);
EMPTY_TO_MINSIZE(so);
PyObject_GC_Track(so);
} else {
so = (PySetObject *)type->tp_alloc(type, 0);
if (so == NULL)
return NULL;
/* tp_alloc has already zeroed the structure */
assert(so->table == NULL && so->fill == 0 && so->used == 0);
INIT_NONZERO_SET_SLOTS(so);
}
so->lookup = set_lookkey_unicode; so->lookup = set_lookkey_unicode;
so->weakreflist = NULL; so->weakreflist = NULL;
@ -1103,34 +1083,15 @@ frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
int int
PySet_ClearFreeList(void) PySet_ClearFreeList(void)
{ {
int freelist_size = numfree; return 0;
PySetObject *so;
while (numfree) {
numfree--;
so = free_list[numfree];
PyObject_GC_Del(so);
}
return freelist_size;
} }
void void
PySet_Fini(void) PySet_Fini(void)
{ {
PySet_ClearFreeList();
Py_CLEAR(emptyfrozenset); Py_CLEAR(emptyfrozenset);
} }
/* Print summary info about the state of the optimized allocator */
void
_PySet_DebugMallocStats(FILE *out)
{
_PyDebugAllocatorStats(out,
"free PySetObject",
numfree, sizeof(PySetObject));
}
static PyObject * static PyObject *
set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {