8000 Replace sole use of maxdict by lru_cache. · matplotlib/matplotlib@cd18774 · GitHub
[go: up one dir, main page]

Skip to content

Commit cd18774

Browse files
committed
Replace sole use of maxdict by lru_cache.
... and expand the cache size, while we're at it.
1 parent 9844e9f commit cd18774

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

lib/matplotlib/tests/test_text.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ 8000 -768,6 +768,8 @@ def test_pdf_chars_beyond_bmp():
768768

769769
@needs_usetex
770770
def test_metrics_cache():
771+
mpl.text._get_text_metrics_with_cache_impl.cache_clear()
772+
771773
fig = plt.figure()
772774
fig.text(.3, .5, "foo\nbar")
773775
fig.text(.3, .5, "foo\nbar", usetex=True)
@@ -788,3 +790,8 @@ def call(*args, **kwargs):
788790
# collision with the non-TeX string (drawn first here) whose metrics would
789791
# get incorrectly reused by the first TeX string.
790792
assert len(ys["foo"]) == len(ys["bar"]) == 1
793+
794+
info = mpl.text._get_text_metrics_with_cache_impl.cache_info()
795+
# Even string gets a miss for the first layouting (extents), then a hit
796+
# when drawing, but "foo\nbar" gets two hits as it's drawn twice.
797+
assert info.hits > info.misses

lib/matplotlib/text.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Classes for including text in a figure.
33
"""
44

5+
import functools
56
import logging
67
import math
78
import numbers
@@ -89,6 +90,22 @@ def _get_textbox(text, renderer):
8990
return x_box, y_box, w_box, h_box
9091

9192

93+
def _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi):
94+
"""Call ``renderer.get_text_width_height_descent``, caching the results."""
95+
# Resolve the actual path corresponding to fontprop so that later in-place
96+
# mutations of fontprop do not mess up the cache. dpi is not used, but
97+
# participates in cache invalidation (via the renderer).
98+
normalized_fp = FontProperties(fname=mpl.font_manager.findfont(fontprop))
99+
return _get_text_metrics_with_cache_impl(
100+
weakref.ref(renderer), text, normalized_fp, ismath, dpi)
101+
102+
103+
@functools.lru_cache(4096)
104+
def _get_text_metrics_with_cache_impl(
105+
renderer_ref, text, fontprop, ismath, dpi):
106+
return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)
107+
108+
92109
@docstring.interpd
93110
@cbook._define_aliases({
94111
"color": ["c"],
@@ -108,7 +125,6 @@ class Text(Artist):
108125
"""Handle storing and drawing of text in window or data coordinates."""
109126

110127
zorder = 3
111-
_cached = cbook.maxdict(50)
112128

113129
def __repr__(self):
114130
return "Text(%s, %s, %s)" % (self._x, self._y, repr(self._text))
@@ -273,23 +289,6 @@ def update_from(self, other):
273289
self._linespacing = other._linespacing
274290
self.stale = True
275291

276-
def _get_text_metrics_with_cache(
277-
self, renderer, text, fontproperties, ismath):
278-
"""
279-
Call ``renderer.get_text_width_height_descent``, caching the results.
280-
"""
281-
cache_key = (
282-
weakref.ref(renderer),
283-
text,
284-
hash(fontproperties),
285-
ismath,
286-
self.figure.dpi,
287-
)
288-
if cache_key not in self._cached:
289-
self._cached[cache_key] = renderer.get_text_width_height_descent(
290-
text, fontproperties, ismath)
291-
return self._cached[cache_key]
292-
293292
def _get_layout(self, renderer):
294293
"""
295294
Return the extent (bbox) of the text together with
@@ -305,16 +304,17 @@ def _get_layout(self, renderer):
305304
ys = []
306305

307306
# Full vertical extent of font, including ascenders and descenders:
308-
_, lp_h, lp_d = self._get_text_metrics_with_cache(
307+
_, lp_h, lp_d = _get_text_metrics_with_cache(
309308
renderer, "lp", self._fontproperties,
310-
ismath="TeX" if self.get_usetex() else False)
309+
ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
311310
min_dy = (lp_h - lp_d) * self._linespacing
312311

313312
for i, line in enumerate(lines):
314313
clean_line, ismath = self._preprocess_math(line)
315314
if clean_line:
316-
w, h, d = self._get_text_metrics_with_cache(
317-
renderer, clean_line, self._fontproperties, ismath)
315+
w, h, d = _get_text_metrics_with_cache(
316+
renderer, clean_line, self._fontproperties,
317+
ismath=ismath, dpi=self.figure.dpi)
318318
else:
319319
w = h = d = 0
320320

0 commit comments

Comments
 (0)
0