Nice to know (and ideally that’s what one would expect), but the next example hopefully will demonstrate what I meant:
julia>julia> function f(x)
y = (1, 2)
y = [x[1] for i in x]
g(_) = y
return g(x)
end
f (generic function with 1 method)
julia> @code_warntype f([1.0, 2.0])
Variables
#self#::Core.Const(f)
x::Vector{Float64}
#67::var"#67#68"{Vector{Float64}}
g::var"#g#69"
y::Core.Box
Body::Any
1 ─ (y = Core.Box())
│ %2 = Core.tuple(1, 2)::Core.Const((1, 2))
│ Core.setfield!(y, :contents, %2)
│ %4 = Main.:(var"#67#68")::Core.Const(var"#67#68")
│ %5 = Core.typeof(x)::Core.Const(Vector{Float64})
│ %6 = Core.apply_type(%4, %5)::Core.Const(var"#67#68"{Vector{Float64}})
│ (#67 = %new(%6, x))
│ %8 = #67::var"#67#68"{Vector{Float64}}
│ %9 = Base.Generator(%8, x)::Base.Generator{Vector{Float64}, var"#67#68"{Vector{Float64}}}
│ %10 = Base.collect(%9)::Vector{Float64}
│ Core.setfield!(y, :contents, %10)
│ (g = %new(Main.:(var"#g#69"), y))
│ %13 = (g)(x)::Any
└── return %13
julia> @time f([1.0, 2.0])
0.000001 seconds (3 allocations: 208 bytes)
2-element Vector{Float64}:
1.0
1.0
julia> @time f([1.0, 2.0])
0.000000 seconds (3 allocations: 208 bytes)
2-element Vector{Float64}:
1.0
1.0
Deleting the problematic line, results in inferred type:
julia> function f(x)
#y = (1, 2)
y = [x[1] for i in x]
g(_) = y
return g(x)
end
f (generic function with 1 method)
julia> @code_warntype f([1.0, 2.0])
Variables
#self#::Core.Const(f)
x::Vector{Float64}
#70::var"#70#71"{Vector{Float64}}
g::var"#g#72"{Vector{Float64}}
y::Vector{Float64}
Body::Vector{Float64}
1 ─ %1 = Main.:(var"#70#71")::Core.Const(var"#70#71")
│ %2 = Core.typeof(x)::Core.Const(Vector{Float64})
│ %3 = Core.apply_type(%1, %2)::Core.Const(var"#70#71"{Vector{Float64}})
│ (#70 = %new(%3, x))
│ %5 = #70::var"#70#71"{Vector{Float64}}
│ %6 = Base.Generator(%5, x)::Base.Generator{Vector{Float64}, var"#70#71"{Vector{Float64}}}
│ (y = Base.collect(%6))
│ %8 = Main.:(var"#g#72")::Core.Const(var"#g#72")
│ %9 = Core.typeof(y)::Core.Const(Vector{Float64})
│ %10 = Core.apply_type(%8, %9)::Core.Const(var"#g#72"{Vector{Float64}})
│ (g = %new(%10, y))
│ %12 = (g)(x)::Vector{Float64}
└── return %12
julia> @time f([1.0, 2.0])
0.000001 seconds (2 allocations: 192 bytes)
2-element Vector{Float64}:
1.0
1.0
julia> @time f([1.0, 2.0])
0.000000 seconds (2 allocations: 192 bytes)
2-element Vector{Float64}:
1.0
1.0
So @code_warntype
is clean now.
So am I breaking some of the performance tips?