The code below compares the results when computing a function when it is returned from another to when it is defined directly. Why is the returned version so much slower, and require any allocations at all? I can see from looking at @code_warntype Fnc!(q, x, y, p) that it is probably from type instabilities, but I can’t seem to identify how to resolve this. I need the returned function form for a separate application where a function is constructed from other user-inputs.
function return_fnc(F, P)
Fnc! = (q, x, y, p) -> begin
F, P = p
q[1] = 5F(x, y, P) + 2.0
q[2] = -2F(y, -x, P) + 3.0
return nothing
end
p = F, P
return Fnc!, p
end
function fnc!(q, x, y, p)
F, P = p
q[1] = 5F(x, y, P) + 2.0
q[2] = -2F(y, -x, P) + 3.0
return nothing
end
function benchmarks(q, x, y, Fnc!, p)
res1 = @benchmark Fnc!(q, x, y, p)
res2 = @benchmark fnc!(q, x, y, p)
return res1, res2
end
F = (x, y, p) -> (x + y)/p[1]
P = 1.0
Fnc!, p = return_fnc(F, P)
q = zeros(2); x = 0.5; y = 0.3
res1, res2 = benchmarks(q, x, y, Fnc!, p)
res1
res2
julia> res1
BenchmarkTools.Trial: 10000 samples with 600 evaluations.
Range (min … max): 203.000 ns … 42.437 μs ┊ GC (min … max): 0.00% … 99.27%
Time (median): 266.667 ns ┊ GC (median): 0.00%
Time (mean ± σ): 303.922 ns ± 921.797 ns ┊ GC (mean ± σ): 6.75% ± 2.22%
▇▅▁ ██▅▄▃▂▁ ▂
████▇▇▆█████████▇███▇███▇████▇██▇▇█▇▇█▇▇█▇▇▇▇▇▇▇▇▇▆▇▇▆▇▆▅▆▆▆▅ █
203 ns Histogram: log(frequency) by time 686 ns <
Memory estimate: 176 bytes, allocs estimate: 11.
julia> res2
BenchmarkTools.Trial: 10000 samples with 998 evaluations.
Range (min … max): 23.046 ns … 178.657 ns ┊ GC (min … max): 0.00% … 0.00%
Time (median): 24.148 ns ┊ GC (median): 0.00%
Time (mean ± σ): 27.533 ns ± 11.586 ns ┊ GC (mean ± σ): 0.00% ± 0.00%
▇█▃▄▁ ▂▁ ▂
█████▇▇▆▆▆▇▆▆▇▅▇▆▆██▇▆▆▆▆▆▇▇█████████▇▇▇▇▇▇▇▇█▆▅▅▅▅▅▅▅▅▁▄▃▄▃ █
23 ns Histogram: log(frequency) by time 75.1 ns <
Memory estimate: 0 bytes, allocs estimate: 0.