Skip to content

Commit

Permalink
Add precompiles to reduce time to first Revise.revise()
Browse files Browse the repository at this point in the history
Perhaps the most annoying thing about Revise now is that the first
revision is quite slow, about 3.1s on my machine. This PR drops the time
to about 2.4s. Basically the idea is to precompile statements that
Revise will need.

Discovered via the new snoopi_deep/Core.Compiler.Timings framework.
  • Loading branch information
timholy committed Dec 16, 2020
1 parent 99402b4 commit 4c4e078
Showing 1 changed file with 39 additions and 10 deletions.
49 changes: 39 additions & 10 deletions contrib/generate_precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ UP_ARROW = "\e[A"
DOWN_ARROW = "\e[B"

hardcoded_precompile_statements = """
# used by JuliaInterpreter.jl and Revise.jl
# used by Revise.jl
@assert precompile(Tuple{typeof(Base.parse_cache_header), String})
@assert precompile(Tuple{typeof(pushfirst!), Vector{Any}, Function})
@assert precompile(Tuple{typeof(push!), Set{Module}, Module})
@assert precompile(Tuple{typeof(push!), Set{Method}, Method})
@assert precompile(Tuple{typeof(empty!), Set{Any}})
@assert precompile(Base.read_dependency_src, (String, String))
@assert precompile(Base.CoreLogging.current_logger_for_env, (Base.CoreLogging.LogLevel, String, Module))
# used by Requires.jl
@assert precompile(Tuple{typeof(get!), Type{Vector{Function}}, Dict{Base.PkgId,Vector{Function}}, Base.PkgId})
@assert precompile(Tuple{typeof(haskey), Dict{Base.PkgId,Vector{Function}}, Base.PkgId})
Expand Down Expand Up @@ -56,10 +55,34 @@ cd("complet_path\t\t$CTRL_C
"""

precompile_script = """
# Used by Revise
# Used by Revise & its dependencies
delete!(push!(Set{Module}(), Base), Main)
m = first(methods(+))
delete!(push!(Set{Method}(), m), m)
empty!(Set())
push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two))
(setindex!(Dict{String,Base.PkgId}(), Base.PkgId(Base), "file.jl"))["file.jl"]
(setindex!(Dict{Symbol,Vector{Int}}(), [1], :two))[:two]
(setindex!(Dict{Base.PkgId,String}(), "file.jl", Base.PkgId(Base)))[Base.PkgId(Base)]
(setindex!(Dict{Union{GlobalRef,Symbol}, Vector{Int}}(), [1], :two))[:two]
(setindex!(IdDict{Type, Union{Missing, Vector{Tuple{LineNumberNode, Expr}}}}(), missing, Int))[Int]
Dict{Symbol, Union{Nothing, Bool, Symbol}}(:one => false)[:one]
Dict(Base => [:(1+1)])[Base]
Dict(:one => [1])[:one]
Dict("abc" => Set())["abc"]
pushfirst!([], sum)
get(Base.pkgorigins, Base.PkgId(Base), nothing)
sort!([1,2,3])
unique!([1,2,3])
cumsum([1,2,3])
append!(Int[], BitSet())
isempty(BitSet())
delete!(BitSet([1,2]), 3)
deleteat!(Int32[1,2,3], [1,3])
deleteat!(Any[1,2,3], [1,3])
Core.svec(1, 2) == Core.svec(3, 4)
copy(Core.Compiler.retrieve_code_info(Core.Compiler.specialize_method(which(+, (Int, Int)), [Int, Int], Core.svec())))
any(t->t[1].line > 1, [(LineNumberNode(2,:none),:(1+1))])
"""

julia_exepath() = joinpath(Sys.BINDIR::String, Base.julia_exename())
Expand All @@ -72,21 +95,26 @@ if have_repl
"""
end

# This is disabled because it doesn't give much benefit
# and the code in Distributed is poorly typed causing many invalidations
#=
Distributed = get(Base.loaded_modules,
Base.PkgId(Base.UUID("8ba89e20-285c-5b6f-9357-94700520ee1b"), "Distributed"),
nothing)
if Distributed !== nothing
hardcoded_precompile_statements *= """
@assert precompile(Tuple{typeof(Distributed.remotecall),Function,Int,Module,Vararg{Any, 100}})
@assert precompile(Tuple{typeof(Distributed.procs)})
@assert precompile(Tuple{typeof(Distributed.finalize_ref), Distributed.Future})
"""
# This is disabled because it doesn't give much benefit
# and the code in Distributed is poorly typed causing many invalidations
#=
precompile_script *= """
using Distributed
addprocs(2)
pmap(x->iseven(x) ? 1 : 0, 1:4)
@distributed (+) for i = 1:100 Int(rand(Bool)) end
"""
end
=#
end


Artifacts = get(Base.loaded_modules,
Expand Down Expand Up @@ -121,6 +149,7 @@ if FileWatching !== nothing
hardcoded_precompile_statements *= """
@assert precompile(Tuple{typeof(FileWatching.watch_file), String, Float64})
@assert precompile(Tuple{typeof(FileWatching.watch_file), String, Int})
@assert precompile(Tuple{typeof(FileWatching._uv_hook_close), FileWatching.FileMonitor})
"""
end

Expand Down

0 comments on commit 4c4e078

Please sign in to comment.