Skip to content

Commit 3070b71

Browse files
authored
bpo-32422: Reduce lru_cache memory usage (GH-5008)
1 parent 0cf16f9 commit 3070b71

File tree

2 files changed

+8
-26
lines changed

2 files changed

+8
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
``functools.lru_cache`` uses less memory (3 words for each cached key) and
2+
takes about 1/3 time for cyclic GC.

Modules/_functoolsmodule.c

+6-26
Original file line numberDiff line numberDiff line change
@@ -677,26 +677,9 @@ typedef struct lru_list_elem {
677677
static void
678678
lru_list_elem_dealloc(lru_list_elem *link)
679679
{
680-
_PyObject_GC_UNTRACK(link);
681680
Py_XDECREF(link->key);
682681
Py_XDECREF(link->result);
683-
PyObject_GC_Del(link);
684-
}
685-
686-
static int
687-
lru_list_elem_traverse(lru_list_elem *link, visitproc visit, void *arg)
688-
{
689-
Py_VISIT(link->key);
690-
Py_VISIT(link->result);
691-
return 0;
692-
}
693-
694-
static int
695-
lru_list_elem_clear(lru_list_elem *link)
696-
{
697-
Py_CLEAR(link->key);
698-
Py_CLEAR(link->result);
699-
return 0;
682+
PyObject_Del(link);
700683
}
701684

702685
static PyTypeObject lru_list_elem_type = {
@@ -720,10 +703,7 @@ static PyTypeObject lru_list_elem_type = {
720703
0, /* tp_getattro */
721704
0, /* tp_setattro */
722705
0, /* tp_as_buffer */
723-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
724-
0, /* tp_doc */
725-
(traverseproc)lru_list_elem_traverse, /* tp_traverse */
726-
(inquiry)lru_list_elem_clear, /* tp_clear */
706+
Py_TPFLAGS_DEFAULT, /* tp_flags */
727707
};
728708

729709

@@ -959,8 +939,8 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
959939
}
960940
} else {
961941
/* Put result in a new link at the front of the queue. */
962-
link = (lru_list_elem *)PyObject_GC_New(lru_list_elem,
963-
&lru_list_elem_type);
942+
link = (lru_list_elem *)PyObject_New(lru_list_elem,
943+
&lru_list_elem_type);
964944
if (link == NULL) {
965945
Py_DECREF(key);
966946
Py_DECREF(result);
@@ -970,7 +950,6 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
970950
link->hash = hash;
971951
link->key = key;
972952
link->result = result;
973-
_PyObject_GC_TRACK(link);
974953
if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
975954
hash) < 0) {
976955
Py_DECREF(link);
@@ -1151,7 +1130,8 @@ lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
11511130
lru_list_elem *link = self->root.next;
11521131
while (link != &self->root) {
11531132
lru_list_elem *next = link->next;
1154-
Py_VISIT(link);
1133+
Py_VISIT(link->key);
1134+
Py_VISIT(link->result);
11551135
link = next;
11561136
}
11571137
Py_VISIT(self->maxsize_O);

0 commit comments

Comments
 (0)