I ran a type-stability check on my code recently. When I call @code_warntype
on it, I get the following output:
Variables:
#unused#::IHT.#kw##L0_reg
#temp#@_2::Array{Any,1}
::IHT.#L0_reg
x::Array{Float64,2}
y::Array{Float64,1}
k::Int64
#temp#@_7::Bool
#temp#@_8::Bool
max_iter::Int64
max_step::Int64
quiet::Bool
v::IHT.IHTVariables{Float64,Array{Float64,1}}
tol::Float64
#temp#@_14::Int64
#temp#@_15::Int64
#temp#@_16::Int64
#temp#@_17::Any
###...###
#temp#@_17::Any = (Core.arrayref(#temp#@_2::Array{Any,1},#temp#@_16::Int64)::Any
###...###
v::IHT.IHTVariables{Float64,Array{Float64,1}} = (Core.typeassert)((Core.arrayref)(#temp#@_2::Array{Any,1},(Base.box)(Int64,(Base.add_int)(#temp#@_16::Int64,1)))::Any,IHT.IHTVariables{Float64,Array{Float64,1}})::IHT.IHTVariables{Float64,Array{Float64,1}}
Minimal working example, using my IHT.jl package:
Pkg.clone("https://github.com/klkeys/IHT.jl")
n = 100; p = 250; k = 2;
x = randn(n,p)
b = zeros(p); b[1:k] = randn(k); shuffle!(b)
y = x*b + randn(n)
@code_warntype L0_reg(x, y, k, quiet=true)
It would seem like the compiler is using #temp#
to read the arguments to the function L0_reg
. The function arguments are completely specified. From where does this evil little #temp#@_2
variable arise? Am I able to tell the compiler what its type is? (hopefully not Array{Any,1}
...)
You can use
@code_lowered
to view where the#temp#
variables are coming from:In this case, the temps (in particular
#temp#@_2
) are coming from the keyword arguments. This is quite normal for keyword arguments.Keyword arguments are known to have callsite overhead that can be somewhat worked around by declaring types. Note that unless your function does very little, it's unlikely the sorting of keyword arguments is actually a huge bottleneck (despite the nasty
@code_warntype
output).When you do
@code_warntype
on a keyword argument call, you're actually viewing the type instabilities of the keyword argument sorter, an autogenerated wrapper around the real function. As you can see, the code ends up calling(IHT.#L0_reg#75)(temp,tol,max_iter,max_step,quiet,,x,y,k)
, which is a plain function that takes positional arguments. So the output of@code_warntype
is almost useless in this case.