Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit da181d3

Browse filesBrowse files
authored
Merge pull request #10804 from tacaswell/rev_lru_cache
Rev lru cache
2 parents 47bebe9 + b8fc0e7 commit da181d3
Copy full SHA for da181d3

File tree

Expand file treeCollapse file tree

7 files changed

+64
-43
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+64
-43
lines changed

‎lib/matplotlib/backends/backend_agg.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_agg.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
from matplotlib import cbook, rcParams, __version__
3232
from matplotlib.backend_bases import (
3333
_Backend, FigureCanvasBase, FigureManagerBase, RendererBase, cursors)
34+
from matplotlib.cbook import maxdict
35+
from matplotlib.figure import Figure
3436
from matplotlib.font_manager import findfont, get_font
3537
from matplotlib.ft2font import (LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING,
3638
LOAD_DEFAULT, LOAD_NO_AUTOHINT)

‎lib/matplotlib/backends/backend_svg.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_svg.py
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from matplotlib.backend_bases import (
2323
_Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
2424
from matplotlib.backends.backend_mixed import MixedModeRenderer
25+
from matplotlib.cbook import is_writable_file_like, maxdict
2526
from matplotlib.colors import rgb2hex
2627
from matplotlib.font_manager import findfont, get_font
2728
from matplotlib.ft2font import LOAD_NO_HINTING
@@ -259,6 +260,9 @@ def generate_css(attrib={}):
259260

260261
_capstyle_d = {'projecting' : 'square', 'butt' : 'butt', 'round': 'round',}
261262
class RendererSVG(RendererBase):
263+
FONT_SCALE = 100.0
264+
fontd = maxdict(50)
265+
262266
def __init__(self, width, height, svgwriter, basename=None, image_dpi=72):
263267
self.width = width
264268
self.height = height

‎lib/matplotlib/colors.py

Copy file name to clipboardExpand all lines: lib/matplotlib/colors.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ def _is_nth_color(c):
111111

112112
def is_color_like(c):
113113
"""Return whether *c* can be interpreted as an RGB(A) color."""
114-
# Special-case nth color syntax because it cannot be parsed during setup.
114+
# Special-case nth color syntax because it cannot be parsed during
115+
# setup.
115116
if _is_nth_color(c):
116117
return True
117118
try:

‎lib/matplotlib/font_manager.py

Copy file name to clipboardExpand all lines: lib/matplotlib/font_manager.py
+21-21Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,6 @@ def _normalize_font_family(family):
994994
return family
995995

996996

997-
@cbook.deprecated("2.2")
998997
class TempCache(object):
999998
"""
1000999
A class to store temporary caches that are (a) not saved to disk
@@ -1279,20 +1278,6 @@ def findfont(self, prop, fontext='ttf', directory=None,
12791278
<http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ documentation
12801279
for a description of the font finding algorithm.
12811280
"""
1282-
# Pass the relevant rcParams (and the font manager, as `self`) to
1283-
# _findfont_cached so to prevent using a stale cache entry after an
1284-
# rcParam was changed.
1285-
rc_params = tuple(tuple(rcParams[key]) for key in [
1286-
"font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
1287-
"font.monospace"])
1288-
return self._findfont_cached(
1289-
prop, fontext, directory, fallback_to_default, rebuild_if_missing,
1290-
rc_params)
1291-
1292-
@lru_cache()
1293-
def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
1294-
rebuild_if_missing, rc_params):
1295-
12961281
if not isinstance(prop, FontProperties):
12971282
prop = FontProperties(prop)
12981283
fname = prop.get_file()
@@ -1306,7 +1291,11 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
13061291
else:
13071292
fontlist = self.ttflist
13081293

1309-
if directory is not None:
1294+
if directory is None:
1295+
cached = _lookup_cache[fontext].get(prop)
1296+
if cached is not None:
1297+
return cached
1298+
else:
13101299
directory = os.path.normcase(directory)
13111300

13121301
best_score = 1e64
@@ -1364,20 +1353,26 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
13641353
else:
13651354
raise ValueError("No valid font could be found")
13661355

1356+
if directory is None:
1357+
_lookup_cache[fontext].set(prop, result)
13671358
return result
13681359

1369-
@lru_cache()
1360+
_is_opentype_cff_font_cache = {}
13701361
def is_opentype_cff_font(filename):
13711362
"""
13721363
Returns True if the given font is a Postscript Compact Font Format
13731364
Font embedded in an OpenType wrapper. Used by the PostScript and
13741365
PDF backends that can not subset these fonts.
13751366
"""
13761367
if os.path.splitext(filename)[1].lower() == '.otf':
1377-
with open(filename, 'rb') as fd:
1378-
return fd.read(4) == b"OTTO"
1379-
else:
1380-
return False
1368+
result = _is_opentype_cff_font_cache.get(filename)
1369+
if result is None:
1370+
with open(filename, 'rb') as fd:
1371+
tag = fd.read(4)
1372+
result = (tag == b'OTTO')
1373+
_is_opentype_cff_font_cache[filename] = result
1374+
return result
1375+
return False
13811376

13821377
fontManager = None
13831378
_fmcache = None
@@ -1444,6 +1439,11 @@ def findfont(prop, fontext='ttf'):
14441439

14451440
fontManager = None
14461441

1442+
_lookup_cache = {
1443+
'ttf': TempCache(),
1444+
'afm': TempCache()
1445+
}
1446+
14471447
def _rebuild():
14481448
global fontManager
14491449

‎lib/matplotlib/mathtext.py

Copy file name to clipboardExpand all lines: lib/matplotlib/mathtext.py
+13-9Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,7 @@
2525
import unicodedata
2626
from warnings import warn
2727

28-
try:
29-
from functools import lru_cache
30-
except ImportError: # Py2
31-
from backports.functools_lru_cache import lru_cache
32-
28+
from numpy import inf, isinf
3329
import numpy as np
3430

3531
from pyparsing import (
@@ -41,7 +37,7 @@
4137

4238
from matplotlib import _png, colors as mcolors, get_data_path, rcParams
4339
from matplotlib.afm import AFM
44-
from matplotlib.cbook import Bunch, get_realpath_and_stat
40+
from matplotlib.cbook import Bunch, get_realpath_and_stat, maxdict
4541
from matplotlib.ft2font import FT2Image, KERNING_DEFAULT, LOAD_NO_HINTING
4642
from matplotlib.font_manager import findfont, FontProperties, get_font
4743
from matplotlib._mathtext_data import (latex_to_bakoma, latex_to_standard,
@@ -3251,8 +3247,8 @@ def __init__(self, output):
32513247
Create a MathTextParser for the given backend *output*.
32523248
"""
32533249
self._output = output.lower()
3250+
self._cache = maxdict(50)
32543251

3255-
@lru_cache(50)
32563252
def parse(self, s, dpi = 72, prop = None):
32573253
"""
32583254
Parse the given math expression *s* at the given *dpi*. If
@@ -3264,10 +3260,16 @@ def parse(self, s, dpi = 72, prop = None):
32643260
The results are cached, so multiple calls to :meth:`parse`
32653261
with the same expression should be fast.
32663262
"""
3267-
3263+
# There is a bug in Python 3.x where it leaks frame references,
3264+
# and therefore can't handle this caching
32683265
if prop is None:
32693266
prop = FontProperties()
32703267

3268+
cacheKey = (s, dpi, hash(prop))
3269+
result = self._cache.get(cacheKey)
3270+
if result is not None:
3271+
return result
3272+
32713273
if self._output == 'ps' and rcParams['ps.useafm']:
32723274
font_output = StandardPsFonts(prop)
32733275
else:
@@ -3290,7 +3292,9 @@ def parse(self, s, dpi = 72, prop = None):
32903292

32913293
box = self._parser.parse(s, font_output, fontsize, dpi)
32923294
font_output.set_canvas_size(box.width, box.height, box.depth)
3293-
return font_output.get_results(box)
3295+
result = font_output.get_results(box)
3296+
self._cache[cacheKey] = result
3297+
return result
32943298

32953299
def to_mask(self, texstr, dpi=120, fontsize=14):
32963300
"""

‎lib/matplotlib/path.py

Copy file name to clipboardExpand all lines: lib/matplotlib/path.py
+17-11Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,11 @@
1616

1717
from weakref import WeakValueDictionary
1818

19-
try:
20-
from functools import lru_cache
21-
except ImportError: # Py2
22-
from backports.functools_lru_cache import lru_cache
23-
2419
import numpy as np
2520

2621
from . import _path, rcParams
27-
from .cbook import _to_unmasked_float_array, simple_linear_interpolation
22+
from .cbook import (_to_unmasked_float_array, simple_linear_interpolation,
23+
maxdict)
2824

2925

3026
class Path(object):
@@ -940,17 +936,27 @@ def wedge(cls, theta1, theta2, n=None):
940936
"""
941937
return cls.arc(theta1, theta2, n, True)
942938

943-
@staticmethod
944-
@lru_cache(8)
945-
def hatch(hatchpattern, density=6):
939+
_hatch_dict = maxdict(8)
940+
941+
@classmethod
942+
def hatch(cls, hatchpattern, density=6):
946943
"""
947944
Given a hatch specifier, *hatchpattern*, generates a Path that
948945
can be used in a repeated hatching pattern. *density* is the
949946
number of lines per unit square.
950947
"""
951948
from matplotlib.hatch import get_path
952-
return (get_path(hatchpattern, density)
953-
if hatchpattern is not None else None)
949+
950+
if hatchpattern is None:
951+
return None
952+
953+
hatch_path = cls._hatch_dict.get((hatchpattern, density))
954+
if hatch_path is not None:
955+
return hatch_path
956+
957+
hatch_path = get_path(hatchpattern, density)
958+
cls._hatch_dict[(hatchpattern, density)] = hatch_path
959+
return hatch_path
954960

955961
def clip_to_bbox(self, bbox, inside=True):
956962
"""

‎lib/matplotlib/textpath.py

Copy file name to clipboardExpand all lines: lib/matplotlib/textpath.py
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class TextToPath(object):
3333
DPI = 72
3434

3535
def __init__(self):
36+
"""
37+
Initialization
38+
"""
3639
self.mathtext_parser = MathTextParser('path')
3740
self.tex_font_map = None
3841

@@ -489,7 +492,8 @@ def _revalidate_path(self):
489492
necessary.
490493
491494
"""
492-
if self._invalid or self._cached_vertices is None:
495+
if (self._invalid or
496+
(self._cached_vertices is None)):
493497
tr = Affine2D().scale(
494498
self._size / text_to_path.FONT_SCALE,
495499
self._size / text_to_path.FONT_SCALE).translate(*self._xy)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.