Function array performance

I have an array of functions that each return a float, and so I am trying to assign the results of those functions to an array. So I had something like this

results = similar(f_arr, Float64)
results .= [f(a, b, c) for f in f_arr]

however this is 10+ times slower than manually calling each function in the array, as in

results = similar(f_arr, Float64)
results[1] = f1(a, b, c)
results[2] = f2(a, b, c)
...

Is there an explanation as to why the first way is so slow? I also tried something like the following

results = similar(f_arr, Float64)
results .= [f_arr[i](a, b, c) for i in 1:length(f_arr)]

and I got an error because the tuple (a, b, c) was getting passed to f_arr[i] instead of passing all three variables in the first two code blocks. I am fairly new to Julia so maybe there is some piece of documentation I am missing, and I would love to be pointed in the right direction.

Functions all have their own type so this code isn’t type stable.

You might be able to get some improvement by using a tuple instead.

using BenchmarkTools 

f_array = [sin,cos,tan]
f_tuple = (sin,cos,tan)

x = 1.0

@btime [f($x) for f in f_array];

@btime [f($x) for f in f_tuple];

354.717 ns (11 allocations: 272 bytes)
189.819 ns (3 allocations: 112 bytes)

This turns a tuple into an array, which is not optimal. Try to keep it as a tuple:

1.7.2> @btime ((f,x)->f(x)).($f, $x)
  29.435 ns (0 allocations: 0 bytes)
(0.8414709848078965, 0.5403023058681398, 1.5574077246549023)

Same as yours but a bit more elegant:

julia> @btime map(f->f($x), $f)
  34.945 ns (0 allocations: 0 bytes)
(0.8414709848078965, 0.5403023058681398, 1.5574077246549023)

What is the context for this? Maybe there is a more idiomatic way to represent what you are trying to do.