Reference
Interactive features
SnoopCompileCore.@snoopi
— Macroinf_timing = @snoopi commands
inf_timing = @snoopi tmin=0.0 commands
Execute commands
while snooping on inference. Returns an array of (t, linfo)
tuples, where t
is the amount of time spent infering linfo
(a MethodInstance
).
Methods that take less time than tmin
will not be reported.
SnoopCompileCore.@snoopc
— Macro@snoopc "compiledata.csv" begin
# Commands to execute, in a new process
end
causes the julia compiler to log all functions compiled in the course of executing the commands to the file "compiledata.csv". This file can be used for the input to SnoopCompile.read
.
SnoopCompileCore.@snoopr
— Macrolist = @snoopr expr
Capture method cache invalidations triggered by evaluating expr
. list
is a sequence of invalidated Core.MethodInstance
s together with "explanations," consisting of integers (encoding depth) and strings (documenting the source of an invalidation).
Unless you are working at a low level, you essentially always want to pass list
directly to SnoopCompile.invalidation_trees
.
Extended help
list
is in a format where the "reason" comes after the items. Method deletion results in the sequence
[zero or more (mi, "invalidate_mt_cache") pairs..., zero or more (depth1 tree, loctag) pairs..., method, loctag] with loctag = "jl_method_table_disable"
where mi
means a MethodInstance
. depth1
means a sequence starting at depth=1
.
Method insertion results in the sequence
[zero or more (depth0 tree, sig) pairs..., same info as with delete_method except loctag = "jl_method_table_insert"]
SnoopCompile.parcel
— Functionpc = parcel(calls; subst=[], exclusions=[])
assigns each compile statement to the module that owns the function. Perform string substitution via subst=["Module1"=>"Module2"]
, and omit functions in particular modules with exclusions=["Module3"]
. On output, pc[:Module2]
contains all the precompiles assigned to Module2
.
Use SnoopCompile.write(prefix, pc)
to generate a series of files in directory prefix
, one file per module.
SnoopCompile.write
— Functionwrite(prefix::AbstractString, pc::Dict; always::Bool = false)
Write each modules' precompiles to a separate file. If always
is true, the generated function will always run the precompile statements when called, otherwise the statements will only be called during package precompilation.
SnoopCompile.read
— FunctionSnoopCompile.read("compiledata.csv")
reads the log file produced by the compiler and returns the functions as a pair of arrays. The first array is the amount of time required to compile each function, the second is the corresponding function + types. The functions are sorted in order of increasing compilation time. (The time does not include the cost of nested compiles.)
SnoopCompile.format_userimg
— Functionpc = format_userimg(calls; subst=[], exclusions=[])
generates precompile directives intended for your base/userimg.jl script. Use SnoopCompile.write(filename, pc)
to create a file that you can include
into userimg.jl
.
SnoopCompile.invalidation_trees
— Functiontrees = invalidation_trees(list)
Parse list
, as captured by SnoopCompileCore.@snoopr
, into a set of invalidation trees, where parents nodes were called by their children.
Example
julia> f(x::Int) = 1
f (generic function with 1 method)
julia> f(x::Bool) = 2
f (generic function with 2 methods)
julia> applyf(container) = f(container[1])
applyf (generic function with 1 method)
julia> callapplyf(container) = applyf(container)
callapplyf (generic function with 1 method)
julia> c = Any[1]
1-element Array{Any,1}:
1
julia> callapplyf(c)
1
julia> trees = invalidation_trees(@snoopr f(::AbstractFloat) = 3)
1-element Array{SnoopCompile.MethodInvalidations,1}:
inserting f(::AbstractFloat) in Main at REPL[36]:1 invalidated:
mt_backedges: 1: signature Tuple{typeof(f),Any} triggered MethodInstance for applyf(::Array{Any,1}) (1 children) more specific
See the documentation for further details.
SnoopCompile.filtermod
— Functionthinned = filtermod(module, trees::AbstractVector{MethodInvalidations})
Select just the cases of invalidating a method defined in module
.
SnoopCompile.findcaller
— Functionmethinvs = findcaller(method::Method, trees)
Find a path through trees
that reaches method
. Returns a single MethodInvalidations
object.
Examples
Suppose you know that loading package SomePkg
triggers invalidation of f(data)
. You can find the specific source of invalidation as follows:
f(data) # run once to force compilation
m = @which f(data)
using SnoopCompile
trees = invalidation_trees(@snoopr using SomePkg)
methinvs = findcaller(m, trees)
If you don't know which method to look for, but know some operation that has had added latency, you can look for methods using @snoopi
. For example, suppose that loading SomePkg
makes the next using
statement slow. You can find the source of trouble with
julia> using SnoopCompile
julia> trees = invalidation_trees(@snoopr using SomePkg);
julia> tinf = @snoopi using SomePkg # this second `using` will need to recompile code invalidated above
1-element Array{Tuple{Float64,Core.MethodInstance},1}:
(0.08518409729003906, MethodInstance for require(::Module, ::Symbol))
julia> m = tinf[1][2].def
require(into::Module, mod::Symbol) in Base at loading.jl:887
julia> findcaller(m, trees)
inserting ==(x, y::SomeType) in SomeOtherPkg at /path/to/code:100 invalidated:
backedges: 1: superseding ==(x, y) in Base at operators.jl:83 with MethodInstance for ==(::Symbol, ::Any) (16 children) more specific