- Create
LocalPreferences.toml
with[PrecompileTools] precompile_workloads = false
- Install Plots + HTTP.
- Run
julia +1.10 --project --trace-compile=plots_compile.jl
- Run the following:
julia> @time using Plots
0.740981 seconds (768.54 k allocations: 57.182 MiB, 0.84% gc time, 6.02% compilation time)
julia> @time @eval (p = Plots.plot(rand(10), rand(10)); display(p));
3.452190 seconds (20.40 M allocations: 1.374 GiB, 7.79% gc time, 92.98% compilation time: <1% of which was recompilation)
Make sure the TTFP is slow so to ensure that the precompile workload disabling was effective (cf JuliaLang/PrecompileTools.jl#62). This should generate a plots_compile.jl
with ~ 504 statements.
- Start julia:
julia +1.10 --project --trace-compile=plots_compile_after_include.jl
- Run the following:
julia> using Plots, HTTP
julia> for mod in Base.loaded_modules_order
if !(nameof(mod) in (:Main, :Core, :Base))
Core.eval(@__MODULE__, :(const $(Symbol(mod)) = $mod))
end
end
julia> @time include("plots_compile.jl")
3.429380 seconds (20.86 M allocations: 1.405 GiB, 8.20% gc time, 97.42% compilation time)
true
julia> g() = rand()
julia> g()
julia> @time @eval (p = Plots.plot(rand(10), rand(10)); display(p));
0.292021 seconds (141.86 k allocations: 9.912 MiB, 22.93% compilation time)
- Open up the
plots_compile_after_include.jl
and find theprecompile(Tuple{typeof(Base.rand), Int64})
call and delete everything above it, resulting file will have ~18 signatures.
Now run: julia +1.10 --project
julia> using Plots, HTTP
julia> for mod in Base.loaded_modules_order
if !(nameof(mod) in (:Main, :Core, :Base))
Core.eval(@__MODULE__, :(const $(Symbol(mod)) = $mod))
end
end
julia> @time include("plots_compile.jl")
3.767446 seconds (20.67 M allocations: 1.392 GiB, 8.30% gc time, 97.37% compilation time)
true
julia> @time include("plots_compile_after_include.jl")
0.053578 seconds (128.33 k allocations: 8.950 MiB, 91.61% compilation time)
true
julia> @time @eval (p = Plots.plot(rand(10), rand(10)); display(p));
0.237858 seconds (16.35 k allocations: 1.159 MiB, 2.42% compilation time)
Note the low compilation time on the plot call compared to earlier.
Also, note how including the full plots_compile.jl
twice does not work:
julia> using Plots, HTTP
julia> for mod in Base.loaded_modules_order
if !(nameof(mod) in (:Main, :Core, :Base))
Core.eval(@__MODULE__, :(const $(Symbol(mod)) = $mod))
end
end
julia> @time include("plots_compile.jl")
3.697584 seconds (20.67 M allocations: 1.392 GiB, 8.27% gc time, 97.31% compilation time)
true
julia> @time include("plots_compile.jl")
0.093587 seconds (78.69 k allocations: 4.360 MiB)
true
julia> @time @eval (p = Plots.plot(rand(10), rand(10)); display(p));
0.298213 seconds (142.06 k allocations: 9.929 MiB, 21.79% compilation time)
- Why does replaying the precompile file not remove virtually all compilation time?
- Why is it required to only execute a part of the precompile statements twice to remove the compilation time? What is it about the earlier ones that causes the latter ones to not be effective?
- Is there something special about the signatures of the functions that fail to cache?