Array of functions and allocation

I am trying to understand why arrays of functions allocate. See the following example:

using BenchmarkTools
f1(u,v)=1.0-u-v
fv=Array{Function}(undef,1)
fv[1]=f1
u=0.1
v=0.2
@btime f1($u,$v)
0.001 ns (0 allocations: 0 bytes)
@btime fv[1]($u,$v)
71.178 ns (3 allocations: 48 bytes)

Why is the second approach so (comparatively) slow and why does it allocate? Am I not benchmarking correctly?
I would (naively?) expect that two should be almost identical…

2 Likes

Because Function is an abstract type. If you use a tuple, performance is back:

julia> ft = (f1,)
(f1,)

julia> @btime $ft[1]($u,$v)
  0.016 ns (0 allocations: 0 bytes)
0.7

because

julia> typeof(ft)
Tuple{typeof(f1)}

(also note that you should benchmark the vector with @btime $fv[1]($u,$v))

4 Likes