Why is JuliaC faster than PackageCompiler?

Hi all!

I have been using PackageCompiler for a while to distribute applications in Julia. It usually takes between 20 to 40 minutes to compile an app from scratch. In 1.12 I have been gradually changing it to JuliaC without trimming. This compilation takes no longer than 10 minutes.

I would like to know if JuliaC should be faster than PackageCompiler and why?

5 Likes

I have also noticed the same thing and have been pleasantly surprised :slight_smile: , especially considering it’s built on top of PackageCompiler.jl. Additionally, JuliaC as a drop-in replacement for PC (i.e. no trimming) has also been really nice for my workflow; now it’s a simple cli call (while managing some environment variables).

3 Likes

I suppose you use PackageCompiler.jl (PC) on defaults, and that meaning using create_app, which does build a sysimage, but NOT incrementally (it’s the default for create_sysimage, just not for create_app).

I’m guessing that could be part of the reason, maybe explaining largest part of the speed difference, since the sysimage is large, and you are compiling it again, lots of code you didn’t provide, or might even be using.

You can opt into incremental with create_app, can you just test it out for me (you both)? And if you can also try with --trim? I mean it does “tree shaking” likely an extra step thus taking longer, but not yet working for all code, I would even like to know how fast even if it fails for you.

I see in JuliaC.jl source code:

# If C shim sources are provided, compile them to objects for linking stage

Note JuliaC uses a C compiler also, unlike PC, so while I’ve not looked closely at how implemented; I know code for I/O is implemented differently redirecting to Core (not exact same functionality, but close enough for most I believe), and maybe something related to it is C compiled, and the C compiler faster?

AFAIU, the end result of JuliaC contains much much less code than PackageCompiler. And the way generating a sysimage work, you compile all code in it before you emit it. So less code → faster generation.

I have a Makie GUI where I previously recorded all possible user interactions into a precompile_statements file for PackageCompiler.jl, but does JuliaC.jl also have such option, or does it work efficiently without it?

1 Like