It’s just-ahead-of-time compiled and no «interpreted mode» so it’s always slow to start, if I understand correctly. Really annoying, especially the first time you use it.
If you need to run small scripts and can't switch to a persistent-REPL-based workflow, you might consider starting Julia with the `--compile=min` option. If you know which packages you're going to need, you can also reduce startup times dramatically by building a sysimg with PackageCompiler.jl
There is also technically an interpreter if you want to go that way [1], so in principle it might be possible to do the same trick javascript does, but someone would have to implement that.
Ah, I see. That explains a lot.
Could also be the reason why it beats gfortran in the test. A JIT knows more about the data the program sees/runtime behavior than a normal compiler. Still surprising. Or is gfortran just so much behind state of the art fortran compilers?
Not this test. Julia’s JIT compiler does not know about runtime values, it’s not a tracing JIT like the ones you may be used to. Instead, it’s ‘just ahead of time’, compiling a specialized executable for each new function signature the first time that signature gets hit. I.e. if I do
f(x) = 2x + 1
The first time I call
f(1)
it’ll compile a function specialization for f( ::Int), and the first time you call f on that integer it’ll be slow and all the subsequent calls will be equally fast.
Next if you do
f(1.0 + 2im)
it’ll compile a new specialization for f(::Complex{Float64}) which will be slow the first time while it compiles and then fast on all the subsequent runs.
The genius of Julia’s design is that the JIT compiler is designed around the semantics of multiple dispatch, and the multiple dispatch semantics are designed around having a JIT
That’s strictly accurate but kinda misleading. It doesn’t have multiple optimization passes it does just for hot code paths, it fully compiled per function. They call it Just Ahead Of Time compiled.