Why would a sysimage be faster than a package (JuliaScript.jl)?

As stated in the README, JuliaScript.jl can “create a corresponding julia module and track all precompile statements from the actual run” then “from the second time onwards, it will then run as fast as julia’s precompilation system allows for it.” Alternatively, it could “create a sysimage to improve performance even further.”

I’ve never worked with sysimages so I don’t know the principles, but I assume it would need to load the same code found in a package’s precompile cache. How could it be faster (not sure if it was referring to load time or runtime), do sysimages avoid some sort of overhead?

IIUC, the main difference is in method invalidations and subsequent forced recompilation.
For a precompiled package with precompiled dependencies, Julia loads the precompile cache for each package one by one, needs to check for method redefinitions and recompile anything that got invalidated. A sysimg is essentially the state of Julia after loading all of the packages. So loading a sysimg is basically just copying a file to memory.

2 Likes

That sounds right, but in this particular context there is only one package(ish) or one sysimage made from one script. There wouldn’t be a discrepancy due to multiple packages invalidating each other’s caches.

Well, it depends on the question how many packages your script is using… For my use cases a sysimage reduces the initialization time by a factor of two.

1 Like

Ah that slipped my mind, makes far more sense how it is relevant now. Looking into the source code, the package-ish option seems to PrecompileTools.@recompile_invalidations over imports of the dependencies before running the precompile statements collected from the first run. Wouldn’t that also cache the result of importing the dependencies? Or now I think about it, does that exclude the invalidations caused by the script’s precompile statements?