my aim is to speed up my julia development environment. I am already using __precompile__(false) for my developed package and Revise as much as possible, but if the julia process restarts, it really takes long for the package to load initially. Like too long.
Is there a possibility to preserve the cache from one julia process to use it in a next one? I mean all these jit compilations are already done, it would be so cool if they could simply be reused.
Is there a command line argument for this or some other way?
PrecompileTools require __precompile__(true) in order to work, and makes precompilation even slower (because of the example case which needs to run for tracking precompile statements). Not ideal for development
Fundamentally the challenge here is cache-invalidation and knowing that a cache file can be reused.
In Julia we track the validity across sessions and the package boundary. So when we load a package image we check that all the dependencies are the same as before and that all the source files it depends on are the same.
Now within a session we also track validity but at a method level, but instead of it being content-based we have to track the global state of the method table (e.g. the world-age mechanism).
So the answer currently is no. The only way to save state across sessions is to use the system/package image mechanism (Which is what __precompile__(false) opts out off).
I think most people are using the normal precompilation mechanism with Revise to take advantage of the cacheā¦
Could we eventually have a more fine-grained cache? Perhaps, but it is not an easy problem.
Thank you for the details on the existing caching mechanism.
It sounds to me that it might be easier to hope that Revise could eventually also revise struct definitions, constants, etcā¦ that everything is revisable.
Then you really just need to have a constantly open julia session (but even then you may want to shutdown your PC without a huge penaltyā¦)
Could someone make a julia process load a provided cache? Sure, thatās just a sysimage. Could there be a useful way to interactively save a julia process for that cache? Probably not.
First consider the environment. Say you install a package, compile some of its methods (some of which may be inlined in your own methods), then cache the process for next time. Then you decide to update the package and its methods change. Do you throw the cache out completely or just the affected parts? Could the cache store information that allow you to do the latter without compromising performance? Could you update the cache automatically along with the environment? Would such updates be accessible in the current process or do you have to start another one?
Another problem is scoping. For a small example, a mathematical constant is available as the imported Base variable pi, but you could choose to shadow it with pi=80 in a global scope such as Main and work from there. You save that cache and send it to colleague, who starts wondering why all their subsequent trigonometric methods give the wrong numbers. The simple sane solution is to isolate that cache to its own global scope, not affect Main or any module the user makes, and document all the source code that resulted in that cache.
These are exactly what packages and precompilation do, and loosely speaking you see a similar pattern in AOT-compiled languages for reusing compiled code. Interactively saving sessions isnāt a trivial feature, and the languages that have it made many rational tradeoffs that we likely wonāt want and canāt in v1.
I recall a PR or issue somewhere discussing an invalidation-like mechanism for constants, so you donāt have to resort to reassigning non-constant globals and settle for suboptimal code. However, structs and other instantiable types have an extra layer of difficulties, such as existing instances of the obsolete type. Automatic one-to-one replacement with instances of the new type isnāt always feasible, and even when it is, it can cause latency and nasty side effects that method redefinitions donāt. This really is a novel problem, the typical way to implement dynamically replaceable types is non-constancy and suboptimal code. We can already do that, we just donāt.