-
-
Notifications
You must be signed in to change notification settings - Fork 306
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
Improve performance around Axis(3) limits #2115
Conversation
Compile Times benchmarkNote, that these numbers may fluctuate on the CI servers, so take them with a grain of salt. All benchmark results are based on the mean time and negative percent mean faster than the base branch. Note, that GLMakie + WGLMakie run on an emulated GPU, so the runtime benchmark is much slower. Results are from running: using_time = @ctime using Backend
# Compile time
create_time = @ctime fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true)
display_time = @ctime Makie.colorbuffer(display(fig))
# Runtime
create_time = @benchmark fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true)
display_time = @benchmark Makie.colorbuffer(display(fig))
|
I still think we should only update limits on display, before we add the workaround of disabling limit calculation to all kind of 3rd party libraries... This could be quite the easy change, no? |
How does the Axis know it's being displayed? |
Adding something like update_state_before_display!(figlike) # or some better name Here: https:/JuliaPlots/Makie.jl/blob/master/src/display.jl#L62= |
Or better in |
But is it better that display becomes a state mutating thing then? I'm not sure |
I think compute on display is reasonable, One problem I can think of is: do people use reflection (to read axis limits) before display in order to do something? I hope the answer is no |
In that case they could always call And yes it's not pure, I meant that the Figure is not modified by being displayed currently. And this way you'd add limit reset overhead to every display call. |
Wouldn't update on display be an issue when plotting in the repl? I.e. starting with Another option to throttle these kind of updates would be to generalize |
I don't know how that should work, since no other backend has the notion of frames.
Well, I'd say its more like removing the overhead of calling |
Could we do it such that in the And additionally the This leaves the case where someone displays a window and wants to quickly add 1000 lines to it. I still think there should be some way to disable that, no? |
The only situation I can think of why one would need to calculate limits before display, is if someone was querying them to use it in other plots. This could trigger a
I guess we've been defaulting lately to slower but more user friendly solutions, so I guess we should go for 2 + 3. |
As a reference point, AlgebraOfGraphics added a |
c6f206b
to
4c6d107
Compare
I've changed the implementation to However, there's still the problem of all the functions that can save a scene. |
Most of them should use backend_display / backend_show under the hood... I can take a look if you want |
Problem is that that's already Scene, and we don't have the back link to Axis |
Tests pass now, question is if all the places to call |
Guess it would be good to check the docs before merging this ;) |
Seems like performance slows quite a bit if many plots are added in sequence to an Axis. Because each plot triggers a
resize_limits!
, first of all the limits have to be recomputed for all previous plots when a new one is added, and this also triggers tick changes, which trigger layout changes, etc. So all in all this can be quite slow. This PR adds an option to disable thereset_limits!
call, which should mainly be interesting for workflows where all plots are added in one go, without a person looking at the progress. So for example this should probably be used in AlgebraOfGraphics @piever .Also, I noticed dynamic dispatch in the code path that computes the limits in the first place and tried to fix that. I'm not sure if the logic is perfectly right with regards to NaNs, that behavior can be a bit tricky to pin down. For example, what if there's a NaN only in one dimension of a point, do we skip that whole point or use the remaining components. This PR does the latter.
Here's some examples how the PR improves performance:
Many plots in sequence
Before: 4.999897 seconds (206.07 M allocations: 6.235 GiB, 14.02% gc time)
After: 0.255500 seconds (2.88 M allocations: 151.533 MiB)
Single plot
Before: 0.176131 seconds (10.00 M allocations: 305.179 MiB)
After: 0.012864 seconds (92 allocations: 4.203 KiB)
Type of change
Delete options that do not apply:
Checklist