Why is this simple code slow (how to speed it up)

This small code takes about 24 seconds every time on my macbook pro. Is there a way to make it faster ? I run it on commend line as

julia test.jl
using Plots
x = linspace(0.0,2*pi,100);
y = sin.(x);
plot(x,y)
savefig("test.pdf")

I guess… no…?

You can try switch backend to GR.

The first time you run any function in Julia, the function is compiled. Plots functions are particularly heavy when run the first time and since you are starting Julia, calling the functions once and closing Julia again, you will be paying this price every time. So just plot from Jupyter or something so you only pay the compilation price once and then enjoy Julia’s true speed!

2 Likes

You’ve hit on a significant pain point in Julia development right now. Running a plotting command from the command line is pretty much the worst possible case because you’re paying the entire overhead of compiling the (relatively large) plotting libraries for just one plot. As others have suggested, you’ll find that the second plot command is super quick, so keeping your julia session running longer will definitely help. Jupyter (with IJulia.jl) is one excellent way to do this, and it’s what I personally use.

This is, however, still painful, and it’s something that will likely be a high priority once the API changes for the upcoming v1.0 are completed. There’s been some great work on fully pre-compiling packages, such as https://github.com/SimonDanisch/PackageCompiler.jl and I suspect we’ll see a lot more soon.

If you want to know all the details about why that code is slow, Jameson’s JuliaCon talk is very informative: JuliaCon 2017 | AoT or JIT: How Does Julia Work? | Jameson Nash - YouTube

2 Likes

GR is also as slow. I dont like to use jupyter but I can run it in REPL which is fast in subsequent runs. Thanks.

In REPL I run the code as

julia> include("./test.jl")

Is this the best way to run a julia file ?

You can put it in a module in your path.

__precompile__()
module foo

using Plots

export bar, foobar

function bar(n = 100, l = 0.0, u = 2pi)
    x = linspace(l, u, n)
    x, sin.(x)
end

function foobar(filename="test.pdf", n=100, l = 0.0, u = 2pi)
    x, y = bar(l, u, n)
    plot(x, y)
    savefig(filename)
end

end #module

Now

using Revise, foo
foobar()
# edit and save the file foo.jl perhaps using @edit foobar
foobar() #Revise updates to new version you saved automatically

That’s what I do all the time - leaving the REPL up and keep using it for a long time.

Just make sure that the code does not reference any global variable and if so you may be surprised with different behavior when the global variable changes in the environment.