Skip to content

Cache various dviread constructs globally. #10954

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

Merged
merged 1 commit into from
Jul 15, 2018

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Apr 4, 2018

Previously, caching was done at the level of the renderer, so new
renderers would have to reconstruct the PsfontsMap and Adobe encoding
tables. Using a global cache greatly improves the performance:
something like

rcdefaults()
gca().text(.5, .5, "$foo$", usetex=True)

%timeit savefig("/tmp/test.svg")

goes from ~187ms to ~37ms.

%timeit savefig("/tmp/test.pdf")

goes from ~124ms to ~53ms.

Also moves TextToPath's _get_ps_font_map_and_encoding to use a standard
lru_cache.

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code is PEP 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@anntzer anntzer added this to the v3.0 milestone Apr 4, 2018
enc = dviread.Encoding(enc_name)
return {c: i for i, c in enumerate(enc.encoding)}
@cbook.deprecated("3.0")
def tex_font_map(self):
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't this be a property to be backward compatible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup, fixed

Copy link
Member

@jklymak jklymak left a comment

Choose a reason for hiding this comment

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

This seems fine to me, but I don't understand all the details.

@jklymak jklymak requested a review from jkseppan May 2, 2018 16:29
@anntzer anntzer force-pushed the share-dviread-caches branch from 5719548 to 343a672 Compare May 2, 2018 22:35
@anntzer
Copy link
Contributor Author

anntzer commented May 2, 2018

rebased

@@ -808,14 +812,14 @@ class PsfontsMap(object):
"""
__slots__ = ('_font', '_filename')

def __init__(self, filename):
@lru_cache()
def __new__(cls, filename):
Copy link
Member

Choose a reason for hiding this comment

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

This seems a bit dodgy. Would a helper function (still using lru_cache) also work here instead of decorating __new__?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Something like

@lru_cache()
def _psfontmap_factory(filename): return PsfontsMap(filename)

and use the factory function instead? TBH that seems worse to me but if you prefer that form let me know (but I'm not sure I got what you mean).

Copy link
Contributor

Choose a reason for hiding this comment

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

@tacaswell and I talked, and while this, as a gut reaction, feels a bit magical, it's probably the best mix of being direct and magical, versus other solutions. It wouldn't hurt to have a comment or two here, but I'm not going to hold this up for that.

@tacaswell
Copy link
Member

Decorating __new__ seems a bit too clever.....

Previously, caching was done at the level of the renderer, so new
renderers would have to reconstruct the PsfontsMap and Adobe encoding
tables.  Using a global cache greatly improves the performance:
something like

    rcdefaults()
    gca().text(.5, .5, "$foo$", usetex=True)

    %timeit savefig("/tmp/test.svg")

goes from ~187ms to ~37ms.

    %timeit savefig("/tmp/test.pdf")

goes from ~124ms to ~53ms.

Also moves TextToPath's _get_ps_font_map_and_encoding to use a standard
lru_cache.
@anntzer anntzer force-pushed the share-dviread-caches branch from 776fcb3 to cb58589 Compare July 1, 2018 07:31
@anntzer
Copy link
Contributor Author

anntzer commented Jul 7, 2018

Marking as release critical as it already has one positive review and the gain in performance is quite big.
@tacaswell I can handle your comment in whichever way you prefer (see above), just let me know.

@anntzer anntzer added the Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. label Jul 7, 2018
@dopplershift dopplershift merged commit edd053d into matplotlib:master Jul 15, 2018
@anntzer anntzer deleted the share-dviread-caches branch July 16, 2018 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Performance Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. topic: text/usetex
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants