Is there any reason a Pluto notebook can be slower than the REPL? When I use @time, it seems like both take the same amount of time to run a particular function (involving sampling from a probabilistic program using Gen.jl and plotting using WGLMakie). However, the plot takes about 1 second longer to update on Pluto. This becomes worse for longer simulations. I’m not sure if this is an issue with WGLMakie or with Pluto using more memory.
Pluto does a little extra work compared to the REPL, like checking dependencies between cells. However, 1 second seems like a lot.
Without knowing more about your specific problem, I’ll throw the generic recommendation of avoiding having too much global state. Prefer function
over let
, and prefer let
over begin
.
A minimal working example that reproduces the behaviour would be nice!
Sorry, I should have provided that in my original post.
using Gen, GLMakie, Statistics
@gen function line_model(xs::Vector{Float64})
slope = ({:slope} ~ normal(0, 1))
intercept = ({:intercept} ~ normal(0, 2))
function y(x)
return slope * x + intercept
end
for (i, x) in enumerate(xs)
({(:y, i)} ~ normal(y(x), 0.5))
end
return y
end;
xs=collect(-5.0:0.5:5.0)
function plot_trace(trace,ax)
xs=Gen.get_args(trace)[1]
y=Gen.get_retval(trace)
y_i=[trace[(:y, i)] for i in 1:length(xs)]
dom=collect(xs[1]:0.1:xs[end])
lines!(ax,dom,y.(dom),color="black")
scatter!(ax,xs,y_i)
end
function sample_models(model,xs)
fig=Figure()
ax=[Axis(fig[i,j]) for j in 1:5 for i in 1:5]
for i in 1:25
trace = Gen.simulate(model, (xs,))
plot_trace(trace,ax[i])
end
[xlims!(ax[i],-5,5) for i in 1:25]
[ylims!(ax[i],-5,5) for i in 1:25]
display(fig)
end
@time sample_models(line_model,xs)
I run the same code through the REPL and in a Pluto notebook. On Pluto, each block is split into a separate cell. Usually I would use GLMakie on my REPL, but Pluto seems to have trouble updating plots using GLMakie (I have to redisplay the figure) so I’m using WGLMakie for both for a fair comparison since afaik WGLMakie is slower than GLMakie.
After the first run (which takes extra time for JIT), I average about 0.75 seconds on my REPL. WGLMakie updates as soon as sample_models
returns the figure. Note that I’m regenerating the figure each time rather than emptying the axes and replotting. I’m doing so because typically I want to run simulations with different inputs and plot separate figures.
On Pluto, @time
says 0.1 seconds, but the plot takes longer to update, seemingly longer than on the REPL. The discrepancy seems to be more apparent when the memory usage of the notebook is higher. Is the difference in the output of @time
just a result of how Pluto is implemented?
Pluto certainly has an overhead.
Are you animating this by calling display again?
That seems like it should be a lot slower, and could potentially be even slower in Pluto.
If the plots are too complex to use observables/mutation, you could take a look at the SpecApi, which allows you to define whole figures as an observable that you can update on new data:
I don’t explicitly call display but I do return the figure so that it displays when I run the function.
Thanks, I’ll look into SpecApi!
Thanks. From the sidebar progress breakdown, it seems like the dependency check overhead is not high. However, I notice that the timer for each plot cell runs for longer than the final time that it shows. So it seems like there is some other process running before the cell completes that Pluto isn’t tracking timewise.