SnoopCompile.jl

SnoopCompile "snoops" on the Julia compiler, causing it to record the functions and argument types it's compiling. From these lists of methods, you can generate lists of precompile directives that may reduce the latency between loading packages and using them to do "real work."

SnoopCompile can also detect and analyze method cache invalidations, which occur when new method definitions alter dispatch in a way that forces Julia to discard previously-compiled code. Any later usage of invalidated methods requires recompilation. Invalidation can trigger a domino effect, in which all users of invalidated code also become invalidated, propagating all the way back to the top-level call. When a source of invalidation can be identified and either eliminated or mitigated, you can reduce the amount of work that the compiler needs to repeat and take better advantage of precompilation.

Background

Julia uses Just-in-time (JIT) compilation to generate the code that runs on your CPU. Broadly speaking, there are two major steps: inference and code generation. Inference is the process of determining the type of each object, which in turn determines which specific methods get called; once type inference is complete, code generation performs optimizations and ultimately generates the assembly language (native code) used on CPUs. Some aspects of this process are documented here.

Every time you load a package in a fresh Julia session, the methods you use need to be JIT-compiled, and this contributes to the latency of using the package. In some circumstances, you can save some of the work to reduce the burden next time. This is called precompilation. Unfortunately, precompilation is not as comprehensive as one might hope. Currently, Julia is only capable of saving inference results (not native code) in the *.ji files that are the result of precompilation. Moreover, there are some significant constraints that sometimes prevent Julia from saving even the inference results; and finally, what does get saved can sometimes be invalidated if later packages provide more specific methods that supersede some of the calls in the precompiled methods.

Despite these limitations, there are cases where precompilation can substantially reduce latency. SnoopCompile is designed to try to make it easy to try precompilation to see whether it produces measurable benefits.

Who should use this package

SnoopCompile is intended primarily for package developers who want to improve the experience for their users. Because the results of SnoopCompile are typically stored in the *.ji precompile files, anyone can take advantage of the reduced latency.

PackageCompiler is an alternative that non-developer users may want to consider for their own workflow. It performs more thorough precompilation than the "standard" usage of SnoopCompile, although one can achieve a similar effect by creating userimg.jl files. However, the cost is vastly increased build times, which for package developers is unlikely to be productive.

Finally, another alternative that reduces latency without any modifications to package files is Revise. It can be used in conjunction with SnoopCompile.