Skip to content

Commit 87085bd

Browse files
authored
Merge pull request #13039 from lazka/speed-up-iter-segments
PERF: Speed up Path.iter_segments()
2 parents 11def88 + 3b8689a commit 87085bd

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Path code types like ``Path.MOVETO`` are now ``np.uint8`` instead of ``int``
2+
````````````````````````````````````````````````````````````````````````````
3+
4+
``Path.STOP``, ``Path.MOVETO``, ``Path.LINETO``, ``Path.CURVE3``,
5+
``Path.CURVE4`` and ``Path.CLOSEPOLY`` are now of the type ``Path.code_type``
6+
(``np.uint8`` by default) instead of plain ``int``. This makes their type
7+
match the array value type of the ``Path.codes`` array.

lib/matplotlib/path.py

+18-20
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ class Path(object):
7474
7575
"""
7676

77+
code_type = np.uint8
78+
7779
# Path codes
78-
STOP = 0 # 1 vertex
79-
MOVETO = 1 # 1 vertex
80-
LINETO = 2 # 1 vertex
81-
CURVE3 = 3 # 2 vertices
82-
CURVE4 = 4 # 3 vertices
83-
CLOSEPOLY = 79 # 1 vertex
80+
STOP = code_type(0) # 1 vertex
81+
MOVETO = code_type(1) # 1 vertex
82+
LINETO = code_type(2) # 1 vertex
83+
CURVE3 = code_type(3) # 2 vertices
84+
CURVE4 = code_type(4) # 3 vertices
85+
CLOSEPOLY = code_type(79) # 1 vertex
8486

8587
#: A dictionary mapping Path codes to the number of vertices that the
8688
#: code expects.
@@ -91,8 +93,6 @@ class Path(object):
9193
CURVE4: 3,
9294
CLOSEPOLY: 1}
9395

94-
code_type = np.uint8
95-
9696
def __init__(self, vertices, codes=None, _interpolation_steps=1,
9797
closed=False, readonly=False):
9898
"""
@@ -399,24 +399,22 @@ def iter_segments(self, transform=None, remove_nans=True, clip=None,
399399
snap=snap, stroke_width=stroke_width,
400400
simplify=simplify, curves=curves,
401401
sketch=sketch)
402-
vertices = cleaned.vertices
403-
codes = cleaned.codes
404-
len_vertices = vertices.shape[0]
405402

406403
# Cache these object lookups for performance in the loop.
407404
NUM_VERTICES_FOR_CODE = self.NUM_VERTICES_FOR_CODE
408405
STOP = self.STOP
409406

410-
i = 0
411-
while i < len_vertices:
412-
code = codes[i]
407+
vertices = iter(cleaned.vertices)
408+
codes = iter(cleaned.codes)
409+
for curr_vertices, code in zip(vertices, codes):
413410
if code == STOP:
414-
return
415-
else:
416-
num_vertices = NUM_VERTICES_FOR_CODE[code]
417-
curr_vertices = vertices[i:i+num_vertices].flatten()
418-
yield curr_vertices, code
419-
i += num_vertices
411+
break
412+
extra_vertices = NUM_VERTICES_FOR_CODE[code] - 1
413+
if extra_vertices:
414+
for i in range(extra_vertices):
415+
next(codes)
416+
curr_vertices = np.append(curr_vertices, next(vertices))
417+
yield curr_vertices, code
420418

421419
def cleaned(self, transform=None, remove_nans=False, clip=None,
422420
quantize=False, simplify=False, curves=False,

0 commit comments

Comments
 (0)