Skip to content
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

Invalidate font manager when rcParam family lists change. #3077

Merged
merged 3 commits into from May 22, 2014

Conversation

mdboom
Copy link
Member

@mdboom mdboom commented May 19, 2014

A possible fix for #3074 and related issues.

@mdboom
Copy link
Member Author

mdboom commented May 19, 2014

If this works, I'd advocate merging this *instead of * #3074, as this (hopefully) fixes the underlying problem.

@efiring
Copy link
Member

efiring commented May 19, 2014

@mdboom, sorry, I was too quick to merge #3074.
The solution you have here certainly looks like it would do the job, and I have no objection to using it. It seems like there should be a simpler way, though, that would not require quite so much work with each lookup.
Rough idea, based on the idea that rcParams changes are not made often: save a global hash of the entire rcParams whenever rcParams is changed. Make that part of the lookup key along with the font properties. Or, save it upon each lookup, and clear the lookup caches if it has changed.

@mdboom
Copy link
Member Author

mdboom commented May 19, 2014

I actually spent some time investigating the first option (generating a global hash of the rcParams when they change) but there are an awful lot of entry points to where rcParams can change (reloading from a file, the context manager, changing a value directly), and this wasn't really baked in from the start. Plus, there seems to be no reason to invalidate the cache if an unrelated parameter has changed.

@efiring
Copy link
Member

efiring commented May 19, 2014

@mdboom, Agreed; I was just trying to avoid remaking the rcParams key every time. In fact, I don't have a clear picture of how often the lookup occurs; the overhead of remaking the rcParams key might be utterly negligible. I suspect it is.
I also suspect you know exactly how to undo #3074 most cleanly and efficiently--maybe by directly undoing it's changeset with a second commit to the present PR? That should trigger another Travis test with everything the way we want it to be, at which point this PR can be merged, with smiles all around.

@tacaswell tacaswell added this to the v1.4.0 milestone May 19, 2014
"""
# A list of rcparam names that, when changed, invalidated this
# cache.
invalidating_rcparams = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might want to make this a set for trivial performance boost (<30ns per lookup)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tacaswell, actually, it looks like a tuple is as good or better; but the larger gain--still trivial, about 300 ns out of 1.2 microseconds in a simplified test--is from replacing the key generation loop with a list comprehension:

key = [id(fontManager)] + [rcParams[param] for param in self.invalidating_rcparams]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. I'll make these changes.

@mdboom
Copy link
Member Author

mdboom commented May 19, 2014

I'm going to restart the build, to make sure this wasn't a fluke ;)

@efiring
Copy link
Member

efiring commented May 19, 2014

Looks good. Now, it's just that pesky CHANGELOG entry...

@tacaswell tacaswell merged commit 0f25c75 into matplotlib:master May 22, 2014
@tacaswell
Copy link
Member

Added CHANGELOG (0456e5a) and merged (69109de)

tacaswell added a commit to tacaswell/matplotlib that referenced this pull request Jul 18, 2014
According to the data
model (https://docs.python.org/2/reference/datamodel.html#object.__hash__)
objects that define __hash__ need to define __eq__ or __cmp__.  By
default, all user defined classes have a __cmp__ which evaluates to
False for all other objects.

Previously we do not define either __cmp__ or __eq__ on FontProperties,

This results in never finding the property
cached in the dict, hence the growth in the number of
FontProperties (and I assume the stuff in them).

By adding __eq__ and __ne__ we complete the data model and adding
FontProperties to dictionaries should work as expected.

This was not a problem before, but in matplotlib#3077 the caching key was changed
from hash(prop) -> prop.

Closes matplotlib#3264
joferkington pushed a commit to joferkington/matplotlib that referenced this pull request Jul 23, 2014
According to the data
model (https://docs.python.org/2/reference/datamodel.html#object.__hash__)
objects that define __hash__ need to define __eq__ or __cmp__.  By
default, all user defined classes have a __cmp__ which evaluates to
False for all other objects.

Previously we do not define either __cmp__ or __eq__ on FontProperties,

This results in never finding the property
cached in the dict, hence the growth in the number of
FontProperties (and I assume the stuff in them).

By adding __eq__ and __ne__ we complete the data model and adding
FontProperties to dictionaries should work as expected.

This was not a problem before, but in matplotlib#3077 the caching key was changed
from hash(prop) -> prop.

Closes matplotlib#3264
@mdboom mdboom deleted the font-manager-state branch August 7, 2014 13:50
jbmohler pushed a commit to jbmohler/matplotlib that referenced this pull request Aug 14, 2014
According to the data
model (https://docs.python.org/2/reference/datamodel.html#object.__hash__)
objects that define __hash__ need to define __eq__ or __cmp__.  By
default, all user defined classes have a __cmp__ which evaluates to
False for all other objects.

Previously we do not define either __cmp__ or __eq__ on FontProperties,

This results in never finding the property
cached in the dict, hence the growth in the number of
FontProperties (and I assume the stuff in them).

By adding __eq__ and __ne__ we complete the data model and adding
FontProperties to dictionaries should work as expected.

This was not a problem before, but in matplotlib#3077 the caching key was changed
from hash(prop) -> prop.

Closes matplotlib#3264
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants