Writing a little GUI for visualizing ND data in
GLMakie.jl we noted that the allocations are rather high in Makie, which may be one reason that the startup time is significant.
The data to visualize is minute (e.g. 2x2x2x2), but
julia> a = rand(Float32,2,2,2);
julia> @time ortho!(a)
3.265719 seconds (28.39 M allocations: 1.163 GiB, 6.84% gc time)
The GUI (allocating 1.163 Gb!) has 5
Colorbar and a
Note that this is the allocation consumption starting one call after compilation and not considering the usage during running it and interaction.
I tracked down where the memory is consumed:
# Memory usage:
# Menu: 380 Mb
# Slider, laber, lift: each 5Mb
# hidedecorations: 132 Mb
# Axis: 27 Mb
# heatmap: 2 Mb
# crosshair: 0.26 Mb
# Colorbar: 48 Mb
# colsize!: 8.6 Mb
# rowsize!: 8.6 Mb
# xlims!: 1 Mb
# ylims!: 2 Mb
The gui contains nested grid layouts, which may be part of the problem, but some of the functions seemed to consume unexpectedly large amounts. Most surprisingly
Menu (with only a few entries).
Also 3 seconds to start a visualization is starting to be on the limit of what is practically acceptable.
Any hints, how to reduce Makie`s allocations and improve its speed?
Yeah, we have been noticing that this path is entirely unoptimized… And this sounds much worse than I thought! But I dont think we’re doing anything fundamentally wrong, that couldn’t be made blazingly fast… Would you mind helping to debug these performance problems, by creating minimal working examples that show the slow performance, and help profile them?
I’m also not really sure from what you say - do these times include compilation or not? If they include compilation, that’s sadly way more expected and harder to fix. Maybe you could try PackageCompiler in that case?
Without any code, its pretty impossible for us to help you right now, but if you could point out slow functions etc, it may be pretty easy to fix!
You are of course totally right wrt. a minimal working example would help. Funnily it looked much less serious with such minimal example supposedly since the stuff to relayout upon a change is less? The times and allocations did NOT include compilation times, as I ran the line twice to see the result without compilation, this would also be seen in how time reports it.
hidedecorations! I found a workaround:
hideaxisargs = Dict(:xrectzoom => false, :yrectzoom=>false, :titlevisible=>false,
:bottomspinevisible=>false, :leftspinevisible=>false, :topspinevisible=>false ,:rightspinevisible=>false,
and then calling the axis construction directly with
Axis(fig[2,1],; hideaxisargs...). This saved a couple of hundred megabytes and a speedup in the second range (!) already. My suspicion is that some loop running over the list of arguments, goes through a hell lot of allocations for each argument causing re-layouting for each of something?
As for the menu, it might be something similar?
Yeah if you can find specific things that are slow, it’d be great, since we definitely want to speed this up!
julia> fig = Figure();
julia> ax = Axis(fig[1,1]);
julia> @time hidedecorations!(ax);
0.042182 seconds (584.21 k allocations: 11.154 MiB)
julia> @time menu = Menu(fig[2,1], options = ["option1","option2","option3", "option4"], label="a label", prompt="A promt");
0.053192 seconds (400.46 k allocations: 15.518 MiB)
which grows to about 300 Mb each for
Menu for my complicated figure.
(This time its the current github version of GLMakie: 0.4.6.