Skip to content

Speed up Collection.set_paths #29398

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 3 commits into from
Jan 30, 2025
Merged

Conversation

scottshambaugh
Copy link
Contributor

@scottshambaugh scottshambaugh commented Jan 3, 2025

PR summary

This builds on #16793 to implement __slots__ on Path objects, and to improve a lighter weight creation path. Relative to that MR, it does not modify the garbage collection on Paths, and adds a smattering of minor 3D rendering improvements. For a 200x200 plot_surface test case, I am seeing a 1.3x speedup after averaging over a few profiler runs, though note that this gives better performance over a much wider scope as well.

Relevant issue which this won't fully close: #16659

import time
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = y = np.linspace(-1, 1, 200)
X, Y = np.meshgrid(x, y)
Z = X ** 2 + Y ** 2

print("Timing...")

start_time = time.perf_counter()
ax.plot_surface(X, Y, Z, rstride=1, cstride=1)
fig.canvas.draw()
end_time = time.perf_counter()

plt.close()
print(f"Time taken: {end_time - start_time:.4f} seconds")

PR checklist

@scottshambaugh scottshambaugh marked this pull request as ready for review January 7, 2025 18:59
@scottshambaugh scottshambaugh force-pushed the 3d_speedups_2 branch 3 times, most recently from 3831f2e to 1b256c2 Compare January 8, 2025 18:23
@timhoffm
Copy link
Member

timhoffm commented Jan 8, 2025

How much of the speed up is coming from slots? I would have anticipated that attribute lookups on paths are negligible compared to other operations, and thus the speed up is small. In that case, I would not go for slots as the impose certain restrictions that could become obstacles.

@scottshambaugh
Copy link
Contributor Author

scottshambaugh commented Jan 9, 2025

Not too much is attributable to __slots__ as far as I can tell... the run-to-run profiler variation is high enough that I'm not confident in any changes under 10%. I'm not actually how that dunder would show up in a profiler run, but I'm not seeing its line number in the Path init calls. I was basing making the change on the parent PR, but if we want the flexibility of keeping __dict__ that makes sense to me. Removed.

image

@tacaswell
Copy link
Member

To not have a third round, the test that is dropped is not testing anything because path.points is not a known attribute and was causing issues with __slots__.

@tacaswell
Copy link
Member

I would not expect to see __slots__ show up in a profiler as it controls how the pyobjects in c are created (and if they have a __dict__) and would expect memory reduction rather than runtime reduction.

@scottshambaugh
Copy link
Contributor Author

Rebased to main, this is good to go.

Copy link
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

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

Minor suggestions

_to_unmasked_float_array updates

Linting and tweaks

mean zsort

small perf gain

linting

Fix tests

Linting and tweaks

mean zsort

small perf gain

linting

Fix tests

Update lib/matplotlib/collections.py

Co-authored-by: Oscar Gustafsson <oscar.gustafsson@gmail.com>

remove Path __slots__

Code review suggestions
@QuLogic QuLogic merged commit 4cc7f94 into matplotlib:main Jan 30, 2025
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Speeding up Axes3D.plot_surface 4-8x
5 participants