diff options
author | INADA Naoki <methane@users.noreply.github.com> | 2017-12-25 17:03:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-25 17:03:24 (GMT) |
commit | 3070b71e5eedf62e49b8e7dedab75742a5f67ece (patch) | |
tree | fd637252d634ea0c1bcaa16ae5ed4c506875bf93 | |
parent | 0cf16f9ea014b17d398ee3971d4976c698533318 (diff) | |
download | cpython-3070b71e5eedf62e49b8e7dedab75742a5f67ece.zip cpython-3070b71e5eedf62e49b8e7dedab75742a5f67ece.tar.gz cpython-3070b71e5eedf62e49b8e7dedab75742a5f67ece.tar.bz2 |
bpo-32422: Reduce lru_cache memory usage (GH-5008)
-rw-r--r-- | Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst | 2 | ||||
-rw-r--r-- | Modules/_functoolsmodule.c | 32 |
2 files changed, 8 insertions, 26 deletions
diff --git a/Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst b/Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst new file mode 100644 index 0000000..5918c32 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst @@ -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. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index a571045..ff4172d 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -677,26 +677,9 @@ typedef struct lru_list_elem { static void lru_list_elem_dealloc(lru_list_elem *link) { - _PyObject_GC_UNTRACK(link); Py_XDECREF(link->key); Py_XDECREF(link->result); - PyObject_GC_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; + PyObject_Del(link); } static PyTypeObject lru_list_elem_type = { @@ -720,10 +703,7 @@ static PyTypeObject lru_list_elem_type = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)lru_list_elem_traverse, /* tp_traverse */ - (inquiry)lru_list_elem_clear, /* tp_clear */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ }; @@ -959,8 +939,8 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds } } else { /* Put result in a new link at the front of the queue. */ - link = (lru_list_elem *)PyObject_GC_New(lru_list_elem, - &lru_list_elem_type); + link = (lru_list_elem *)PyObject_New(lru_list_elem, + &lru_list_elem_type); if (link == NULL) { Py_DECREF(key); Py_DECREF(result); @@ -970,7 +950,6 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds link->hash = hash; link->key = key; link->result = result; - _PyObject_GC_TRACK(link); if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, hash) < 0) { 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; while (link != &self->root) { lru_list_elem *next = link->next; - Py_VISIT(link); + Py_VISIT(link->key); + Py_VISIT(link->result); link = next; } Py_VISIT(self->maxsize_O); |