I have more a general curiosity about compilation times. Some software in low-level languages (C, Fortran, C++) that we download from time to time take several minutes to compile. Nevertheless, their execution needs to be snappy. I never experienced a prohibitive loading time in Julia (after pre-compilation). Is that because even large code-bases like Plots get mostly pre-compiled? Or because the jit compilation is for some reason much faster than “standard” compilation? Or there will be corner cases in which compilation time can become prohibitive, and those are simply not very common?
The name precompilation is quite the misnomer (currently). It doesn’t actually do native code compilation. Where ahead-of-time native code compilation exists is in the Julia system image and in external libraries that you use. I think for your use cases, you’re leaning on those more heavily than you think you are. Plots, for example, is a middle API that simply connects Julia to a compiled third-party backend (like GR by default).
Where you see pretty bad compile times is when you can no longer rely on the common set of tools that Julia itself compiles into the system image. Some examples include the AD and CUDA toolchains — both of those are essentially starting from scratch and no longer lean on either the system image or third-party compiled libraries. Or — as
we others have recently been addressing — if your loaded packages invalidate some of that core infrastructural ahead-of-time work.
I haven’t built any “huge” Julia programs. Most of the “startup” time that I’ve seen is when initializing the “Package” subsystem and it goes off and does whatever precompilation is required. Granted that precompilation only happens once, and doesn’t get triggered until the module is updated or a newer version of Julia is used.
I suspect if you built a huge Julia program it would end up broken up into a series of modules just for maintainability. In which case you would be hit with that “first use” precompilation when the Package subsystem is initialized.
I feel like if you where to built a huge Julia program but NOT use the Packages features startup may be “laggy” as code is compiled as needed, but I think it would be hard to build a huge Julia program where most of the code needs to be compiled before it can start doing anything.
Not sure if that answers your questions or not…
Even for code written in Julia, or not yet?
Yes, the system image has Julia code compiled to native code. You can do the same with PackageCompiler.jl IIUC some people are working on caching as well, ie. saving native code that has been generated as you work.
Also, my crude understanding is that for code that is really compiled to native code, there is not a big difference between typical statically compiled languages and Julia per unit of code. Maybe it seems different because the compilation is amortized. And of course, as mentioned above, it depends on how much of what you call is already compiled native code.
Out of curiosity, so what precompilaton actually does?
To answer myself, this seems a nice introduction on what precompilaton actually does: