40 seconds to view a simple plot with no data in Makie

I attach a “screen recording” with my phone, as I still need to find a suitable screen recording software.

My computer is pretty fast, so no spec issue. Laptop which runs on i7, has NVIDIA built in gpu, plenty of cache and RAM. I already used it a lot for scientific purposes.

I have the last version of Julia installed.

This is the program:

using GLMakie

x = [1,2,3,4,5] #not used
y = [2,4,6,2,8] #not used

f = Figure(backgroundcolor = :"#f5f0f5")
ax = Axis(f[1, 1], 
    title = "A Makie Axis",
    xlabel = "The x label",
    ylabel = "The y label"
)

display(f)
    
println("Press any key to skip")
readline()

This is the recording:

using @time on display it says:

0.295571 seconds (187.70 k allocations: 13.201 MiB, 99.90% compilation time)

using @time on ax = Axis… says:

23.276775 seconds (30.21 M allocations: 2.008 GiB, 5.65% gc time, 98.04% compilation time: <1% of which was recompilation)

As title says, this is not a suitable amount of time I can wait, I will return to python for data plotting if this issue is intrinsic.

Hi @Enlil50!

What you have just encountered is a classic issue, but it has as much to do with your development workflow as with Makie or Julia themselves.

Julia code needs to be compiled “just in time”, which means the first run of any function is usually slow. However, the subsequent runs are much faster. To benefit from this speedup, the key is to avoid short-lived Julia sessions that only run one script, which is what you get with a terminal-based routine like:

julia myscript.jl  # not good

Instead, most Julia developers launch a REPL at the beginning of the day, and execute all of their code in that same REPL interactively. That way, you only pay the compilation cost once: while waiting 20s for every run is not acceptable, waiting 20s only once is pretty much okay.

In VSCode it is very easy to adopt this workflow: just use Shift + Enter like in a Jupyter notebook, and the current line/block will be run in a dedicated REPL. For more details, check out my blog post on good practices:

https://modernjuliaworkflows.github.io/writing/#running_code

7 Likes

Thanks.

Is it possible to open this Julia REPL in a separate window or to open multiple REPLS?

This way, If I want to run 2 different files sequentially, but want to view their results at the same time in the terminal (I use this term as I need to view more in depth of REPL), I can.

If I have just 1 repl, i can’t.

Another issue is the lack of SUPER + arrows to switch between windows. When using the REPL inside VSC, i need to use the mouse each time

I don’t know about that, but you can check the documentation of the VSCode extension

https://www.julia-vscode.org/docs/stable/

In particular, the command palette has a Julia: connect external REPL option but I have never used it.

That sounds like a VSCode issue more than a Julia issue. You can configure custom shortcuts for VSCode if you want

Which version of Julia are you using? There have been large improvements to latency recently and 40 seconds sounds too much. I don’t use VS Code much but here are the times I get on a moderately powerful laptop, putting your code (except for the readline) in a file a.jl:

julia> @time include("a.jl")
  5.630644 seconds (3.76 M allocations: 267.373 MiB, 6.34% gc time, 20.73% compilation time: 3% of which was recompilation)
GLMakie.Screen(...)

julia> @time include("a.jl")
  0.076596 seconds (68.32 k allocations: 4.484 MiB)
GLMakie.Screen(...)

The first call is fresh after starting a Julia 1.10.2 session.

3 Likes

gdalle gave a big part of the picture; compiling source code to performant native code takes time and it’s not worth jumping the hoops to circumvent that. The obvious follow-up question is “why can’t I cache what I compiled and load it on subsequent REPL sessions?” A script alone is not worth saving because 1) a change to the environment changes what the code does, and loading an obselete cache is dangerous, and 2) running code before includeing the script can change how it behaves, so unconditionally loading its cache would also be dangerous. To make saving compilation safe, a script must be isolated to a module and be attached to an environment, in other words we can precompile a package. Bear in mind that precompilation can’t cover everything possible, since each method has infinite possible call signatures to compile. Instead, package developers manually specify the standard-issue code to save, and installation on an end-user’s machine precompiles that code. Julia has been precompiling packages for a while, but it’s only in recent versions that precompilation and its tooling matured to caching native code, so don’t be surprised if some packages are lagging in this aspect.

I don’t use Makie or GLMakie, so the following information will not satisfy. I looked into Makie.jl/GLMakie/src/precompiles.jl and Makie.jl/src/precompiles.jl on Github (note that GLMakie imports Makie so that cache should also be loaded), and it appears as if the precompilation workloads include display and Axis calls respectively. I haven’t vetted it myself, but that could substantiate why sijo spent a much smaller proportion of the script’s runtime in compilation (maybe time the overall script for comparison). Both Julia and Makie versions would also be important for comparison.

1 Like

I think that just writing “julia” in the terminal lets you in julia REPL, so i can use whatever terminal I want.

I assure different terminals behave as different repls this way.
Just tried it out.

This seems a good behaviour: this way I can cache the compilation of different programs in different repls, without incurring in any duplications of functions names etc.

It just lacks the native VSC debugging and profiling, but I still don’t need it, so it all works now.

Changing the file and including it again leads to minimal compilation times, just the minor adjustment, and the right answer

2 Likes