Julia normally avoids specializing on Type
, but it can be triggered by @code_warntype
and similar macros (has a mention in Performance Tips; currently open issue 32834; illustrated well in issue 23749). It also appears that @btime
does the same thing:
julia> using BenchmarkTools
julia> using MethodAnalysis
julia> f(x::Type) = fieldnames(x)
f (generic function with 1 method)
julia> methodinstances(f)
Core.MethodInstance[]
julia> @btime f(Int8)
45.702 ns (0 allocations: 0 bytes)
()
julia> methodinstances(f) # huh that's odd, it shouldn't specialize
1-element Array{Core.MethodInstance,1}:
MethodInstance for f(::Type{Int8})
julia> f(Int8)
()
julia> methodinstances(f) # so a normal call uses the unspecialized version
2-element Array{Core.MethodInstance,1}:
MethodInstance for f(::Type{Int8})
MethodInstance for f(::Type{T} where T)
julia> f(Int16)
()
julia> methodinstances(f) # yep, normal call still uses the unspecialized version
2-element Array{Core.MethodInstance,1}:
MethodInstance for f(::Type{Int8})
MethodInstance for f(::Type{T} where T)
julia> @btime f(Int32)
46.457 ns (0 allocations: 0 bytes)
()
julia> methodinstances(f) # and a @btime call causes specialization
3-element Array{Core.MethodInstance,1}:
MethodInstance for f(::Type{Int8})
MethodInstance for f(::Type{Int32})
MethodInstance for f(::Type{T} where T)
As mentioned in the issues and illustrated by my example, normal calls use the unspecialized MethodInstance
, even if a specialized one was already created by a @btime
call. So I’m wondering if @btime
is timing the specialized MethodInstance
instead of the unspecialized one. It may not make a difference for my simple example method, but it could for more complicated methods.
P.S. also applies to @time