-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Globally cache single TexManager instances. #13113
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
Globally cache single TexManager instances. #13113
Conversation
|
TexManager.get_font_config has logic to reinitialize itself when rcParams change, so we're safe. |
Hm, losts of magic. This would be ok then, but hard to understand. What's the gain of having just a single instance and is it worth the complexity? |
texmanager caches its results (see rgba_arrayd, grey_arrayd) but right now this caching is only used for a single renderer; the next renderer call (e.g. if one saves to pdf or svg) needs to redo all that computation. Always returning the same instance allows reusing that cache. I initially thought that textpath did the same, but apparently it doesn't, so I guess we don't need to do that; undoing that part. |
8cb06a8
to
4e98088
Compare
There are two hard problems in programming: naming things, cache invalidation, and off-by-one bugs. |
d388dba
to
2fa695f
Compare
This seems to do what you say. How did you test that it does what you say and that there are no adverse consequences? |
Previously each canvas would create its own texmanager instance when it tried to invoke usetex, but now they all use the same instance (well, for that part you can check that the |
So, the only advantage is saving computation time, when two renderes render the same figure (e.g. first to screen and then to PNG)? If that‘s the case, I‘m -0.5 on this. The gain seems limited and the code logic gets more complex (also I‘m still not 100% sure that reusing the cache cannot lead to troubles. OTOH the code of this change is simple enough, so If others feel it‘s worth doing, Iöm fine with that. |
This would also allow not trying to cache TexManager instances at other places; e.g. right now contour handling code caches TexManager instances to figure out the size of tex strings (https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/contour.py#L269); with this PR we could just recreate TexManager on the fly when needed (as we'd always get the same instance). |
Logically, this should be a singleton, as far as I can see. I see only 2 caches. One is the on-disk long-term-persistent cache of pngs etc., which is already global, not instance-specific. The other is _rc_cache, which is just a tiny dictionary. Therefore I don't see how making this a singleton is actually saving much more than the time it takes to make the instance. Am I missing something? I'm inclined to merge it solely on the logical grounds that it should be a singleton; having more than one instance looks pointless. (And I agree that having it as a class is probably also unnecessary, but it looks harmless.) |
Oh, actually I missed the fact that rgba_arrayd and grey_arrayd are class-level caches so are shared across instances, so my argument is not really strong :p |
I'll hold off on merging pending further comment from @efiring |
Maybe we can discuss this briefly on Monday. I'm wondering whether it would make more sense to just make a single instance in the texmanager module, and use that directly elsewhere. Perhaps the argument against that is the instantiation cost it incurs at startup, regardless of whether the TexManager instance is ever actually needed. In addition, it looks to me like it would fail with a RuntimeError on Google App Engine. It looks like someone started to put in a fix for that, but it wasn't completed. So most likely I am just misunderstanding. Another question: in this PR, when the cached instance is returned by new, init is still called, isn't it? If so, we lose a little performance if we try to eliminate the get_texmanager methods. This would not be the case if just made a single instance in the texmanager module, and always used that directly. To avoid the init overhead, wouldn't one need to move all of the init code into new, and make init a no-op? |
2fa695f
to
e8677b6
Compare
GAE is basically not supported, see e.g. references in #8939. Will remove "pretense" of supporting GAE in texmanager in a separate PR (after this one is done).
Yes, my mistake, good catch. Fixed it. Edit: except of course that TexManager does funky stuff like calling |
e8677b6
to
63b94ef
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a minor change or clarification; otherwise, it looks fine.
This allows sharing its caches across renderer instances. (If it was up to me this class would be replaced by module-level functions and a module-level cache, but heh.)
63b94ef
to
5d82059
Compare
This allows sharing its caches across renderer instances.
(If it was up to me this classes would be replaced by module-level
functions and a module-level cache, but heh.)
PR Summary
PR Checklist