mirror of https://github.com/python/cpython.git
bpo-32422: Reduce lru_cache memory usage (GH-5008)
This commit is contained in:
parent
0cf16f9ea0
commit
3070b71e5e
|
@ -0,0 +1,2 @@
|
||||||
|
``functools.lru_cache`` uses less memory (3 words for each cached key) and
|
||||||
|
takes about 1/3 time for cyclic GC.
|
|
@ -677,26 +677,9 @@ typedef struct lru_list_elem {
|
||||||
static void
|
static void
|
||||||
lru_list_elem_dealloc(lru_list_elem *link)
|
lru_list_elem_dealloc(lru_list_elem *link)
|
||||||
{
|
{
|
||||||
_PyObject_GC_UNTRACK(link);
|
|
||||||
Py_XDECREF(link->key);
|
Py_XDECREF(link->key);
|
||||||
Py_XDECREF(link->result);
|
Py_XDECREF(link->result);
|
||||||
PyObject_GC_Del(link);
|
PyObject_Del(link);
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
lru_list_elem_traverse(lru_list_elem *link, visitproc visit, void *arg)
|
|
||||||
{
|
|
||||||
Py_VISIT(link->key);
|
|
||||||
Py_VISIT(link->result);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
lru_list_elem_clear(lru_list_elem *link)
|
|
||||||
{
|
|
||||||
Py_CLEAR(link->key);
|
|
||||||
Py_CLEAR(link->result);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyTypeObject lru_list_elem_type = {
|
static PyTypeObject lru_list_elem_type = {
|
||||||
|
@ -720,10 +703,7 @@ static PyTypeObject lru_list_elem_type = {
|
||||||
0, /* tp_getattro */
|
0, /* tp_getattro */
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||||
0, /* tp_doc */
|
|
||||||
(traverseproc)lru_list_elem_traverse, /* tp_traverse */
|
|
||||||
(inquiry)lru_list_elem_clear, /* tp_clear */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -959,8 +939,8 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Put result in a new link at the front of the queue. */
|
/* Put result in a new link at the front of the queue. */
|
||||||
link = (lru_list_elem *)PyObject_GC_New(lru_list_elem,
|
link = (lru_list_elem *)PyObject_New(lru_list_elem,
|
||||||
&lru_list_elem_type);
|
&lru_list_elem_type);
|
||||||
if (link == NULL) {
|
if (link == NULL) {
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
@ -970,7 +950,6 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
|
||||||
link->hash = hash;
|
link->hash = hash;
|
||||||
link->key = key;
|
link->key = key;
|
||||||
link->result = result;
|
link->result = result;
|
||||||
_PyObject_GC_TRACK(link);
|
|
||||||
if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
|
if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
|
||||||
hash) < 0) {
|
hash) < 0) {
|
||||||
Py_DECREF(link);
|
Py_DECREF(link);
|
||||||
|
@ -1151,7 +1130,8 @@ lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
|
||||||
lru_list_elem *link = self->root.next;
|
lru_list_elem *link = self->root.next;
|
||||||
while (link != &self->root) {
|
while (link != &self->root) {
|
||||||
lru_list_elem *next = link->next;
|
lru_list_elem *next = link->next;
|
||||||
Py_VISIT(link);
|
Py_VISIT(link->key);
|
||||||
|
Py_VISIT(link->result);
|
||||||
link = next;
|
link = next;
|
||||||
}
|
}
|
||||||
Py_VISIT(self->maxsize_O);
|
Py_VISIT(self->maxsize_O);
|
||||||
|
|
Loading…
Reference in New Issue