8000 Micro optimization of plotting (#26303) · matplotlib/matplotlib@b0121b6 · GitHub
[go: up one dir, main page]

Skip to content

Commit b0121b6

Browse files
authored
Micro optimization of plott 8000 ing (#26303)
* optimizations * compile nth color re; fast path for int in isfinite * eliminate generator * eliminate conversion to list and assignment of cid * avoid mutation of dict while iterating * faster minpos construction * whitespace * revert change to shorthand * use math.isfinite
1 parent 887b51e commit b0121b6

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

lib/matplotlib/cbook.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def process(self, s, *args, **kwargs):
286286
"""
287287
if self._signals is not None:
288288
_api.check_in_list(self._signals, signal=s)
289-
for cid, ref in list(self.callbacks.get(s, {}).items()):
289+
for ref in list(self.callbacks.get(s, {}).values()):
290290
func = ref()
291291
if func is not None:
292292
try:
@@ -1690,6 +1690,10 @@ def _safe_first_finite(obj, *, skip_nonfinite=True):
16901690
def safe_isfinite(val):
16911691
if val is None:
16921692
return False
1693+
try:
1694+
return math.isfinite(val)
1695+
except TypeError:
1696+
pass
16931697
try:
16941698
return np.isfinite(val) if np.isscalar(val) else True
16951699
except TypeError:
@@ -1717,7 +1721,10 @@ def safe_isfinite(val):
17171721
raise RuntimeError("matplotlib does not "
17181722
"support generators as input")
17191723
else:
1720-
return next((val for val in obj if safe_isfinite(val)), safe_first_element(obj))
1724+
for val in obj:
1725+
if safe_isfinite(val):
1726+
return val
1727+
return safe_first_element(obj)
17211728

17221729

17231730
def sanitize_sequence(data):

lib/matplotlib/colors.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,12 @@ def _sanitize_extrema(ex):
210210
ret = float(ex)
211211
return ret
212212

213+
_nth_color_re = re.compile(r"\AC[0-9]+\Z")
214+
213215

214216
def _is_nth_color(c):
215217
"""Return whether *c* can be interpreted as an item in the color cycle."""
216-
return isinstance(c, str) and re.match(r"\AC[0-9]+\Z", c)
218+
return isinstance(c, str) and _nth_color_re.match(c)
217219

218220

219221
def is_color_like(c):

lib/matplotlib/transforms.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,14 @@ def set_children(self, *children):
189189
# Parents are stored as weak references, so that if the
190190
# parents are destroyed, references from the children won't
191191
# keep them alive.
192+
id_self = id(self)
192193
for child in children:
193194
# Use weak references so this dictionary won't keep obsolete nodes
194195
# alive; the callback deletes the dictionary entry. This is a
195196
# performance improvement over using WeakValueDictionary.
196197
ref = weakref.ref(
197-
self, lambda _, pop=child._parents.pop, k=id(self): pop(k))
198-
child._parents[id(self)] = ref
198+
self, lambda _, pop=child._parents.pop, k=id_self: pop(k))
199+
child._parents[id_self] = ref
199200

200201
def frozen(self):
201202
"""
@@ -670,6 +671,8 @@ def intersection(bbox1, bbox2):
670671
y1 = np.minimum(bbox1.ymax, bbox2.ymax)
671672
return Bbox([[x0, y0], [x1, y1]]) if x0 <= x1 and y0 <= y1 else None
672673

674+
_default_minpos = np.array([np.inf, np.inf])
675+
673676

674677
class Bbox(BboxBase):
675678
"""
@@ -765,7 +768,7 @@ def __init__(self, points, **kwargs):
765768
raise ValueError('Bbox points must be of the form '
766769
'"[[x0, y0], [x1, y1]]".')
767770
self._points = points
768-
self._minpos = np.array([np.inf, np.inf])
771+
self._minpos = _default_minpos.copy()
769772
self._ignore = True
770773
# it is helpful in some contexts to know if the bbox is a
771774
# default or has been mutated; we store the orig points to
@@ -1773,7 +1776,7 @@ def __array__(self, *args, **kwargs):
17731776

17741777
def __eq__(self, other):
17751778
if getattr(other, "is_affine", False) and hasattr(other, "get_matrix"):
1776-
return np.all(self.get_matrix() == other.get_matrix())
1779+
return (self.get_matrix() == other.get_matrix()).all()
17771780
return NotImplemented
17781781

17791782
def transform(self, values):

0 commit comments

Comments
 (0)
0