Reference

Interactive features

SnoopCompileCore.@snoopiMacro
inf_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.

source
SnoopCompileCore.@snoopcMacro
@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.

source
SnoopCompileCore.@snooprMacro
list = @snoopr expr

Capture method cache invalidations triggered by evaluating expr. list is a sequence of invalidated Core.MethodInstances 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"]
source
SnoopCompile.parcelFunction

pc = 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.

source
SnoopCompile.writeFunction
write(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.

source
SnoopCompile.readFunction

SnoopCompile.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.)

source
SnoopCompile.format_userimgFunction

pc = 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.

source
SnoopCompile.invalidation_treesFunction
trees = 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.

source
SnoopCompile.filtermodFunction
thinned = filtermod(module, trees::AbstractVector{MethodInvalidations})

Select just the cases of invalidating a method defined in module.

source
SnoopCompile.findcallerFunction
methinvs = 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
source