New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stronger references in CachedRepresentation #24954
Comments
comment:1
Idea: SemiWeakValueDictionary will initially create a strong reference to each value (say, by means of a class attribute holding a list containing the items), and gc.collect() will be monkey-patched so that it first removes all strong references kept by SemiWeakValueDictionary before doing the cyclic collection. In that way, the values of SemiWeakValueDictionary would be permanent till the next cyclic garbage collection occurs. Would that work? |
comment:2
Proof of concept:
|
comment:3
Timing:
vs.
|
comment:4
You can't "just" monkey-patch the |
comment:5
Replying to @embray:
You're right. Hm. Then one could perhaps construct a guardian that will not be collected unless a cyclic garbage collection happens, with a |
comment:6
I see two possible implementations, both quite simple: (A) Keep strong references to the last 100 (or whatever number) values inserted in a (B) Keep a strong reference from the value to itself ( I'll try to implement (A). |
comment:7
Replying to @jdemeyer:
I will try to implement (C), which is: (C) create a "guardian" with a reference to itself (so that it will only be deleted during cyclic garbage collection) and create a weak reference with callback from the class SemiWeakValueDictionary to the guardian. The callback function will both restore the weak reference to the guardian and clears the strong references to the values -- and apparently the callback function is only called when a cyclic collection happens. |
comment:8
So, in practice, the main difference between (A) and (C) is when are the strong references cleared? With (A), it would happen after 100 objects have been inserted in a |
comment:9
I thought (C) would work as follows:
That's fine. But something went wrong:
So, why is the static method not callable? What requirements are made for the callback of a weak reference? |
comment:10
Ouch, I found the problem: An unreferenced variable "cls" in the callback function that shouldn't belong there... Nonetheless, so far, I don't get it to work. |
comment:11
Got it. Problem: During creation of the class SWVD, I wanted to refer to an attribute of that class. Apparently it didn't work. So, now, I am setting the class attribute during initialisation of the first instance of that class.
Elements of a SemiWeakValueDictionary aren't immediately deleted:
But they are deleted when a garbage collection happens:
I guess the above would basically work, although I would prefer to define Edit: I also tested |
comment:13
This is my proof-of-concept implementation. It simply adds strong references to the last 64 objects added to the New commits:
|
Commit: |
comment:14
Thats the obvious solution, keep a finite-length lru cache around. |
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
|
comment:17
Replying to @vbraun:
I'm not using a LRU cache, but a much simpler FIFO. |
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
|
comment:20
Fixed a few test failures. |
comment:21
This solves the issue (random slowdowns in the test suite of |
Reviewer: Marc Mezzarobba |
Changed branch from u/jdemeyer/stronger_references_in_cachedrepresentation to |
There is some very bad behaviour related to
CachedRepresentation
caching that I'm observing on #24742 (but this is otherwise unrelated to that ticket):Now, we try again but we first create a strong reference:
This is much faster the second time! In the first example, the caching
of
CachedRepresentation.__classcall__
is pointless since there is nostrong reference to the entry in the cache, so it gets deleted
immediately whenever the
MatrixSpace(ZZ,3,3)
is deleted.This is just the usual
Py_DECREF
of Python objects, it has nothing to do with the cyclic garbage collector: the behaviour remains the same evenwith
gc.disable()
.This makes me think that we might need to change
CachedRepresentation
to use semi-strong references: these would only be deleted by the
cyclic garbage collector but not by a simple
Py_DECREF()
.Component: misc
Author: Jeroen Demeyer
Branch/Commit:
a802f12
Reviewer: Marc Mezzarobba
Issue created by migration from https://trac.sagemath.org/ticket/24954
The text was updated successfully, but these errors were encountered: