Ah, ok. The thing is that Julia does not specialize for the function type if the function is not called from withing the function. Thus, the fix is:
ulia> function slow(f::F, x) where F # annotate F type here !
y = apply(f, x)
for _ in eachindex(y)
end
end
slow (generic function with 1 method)
julia> function run()
for f in [slow, fast]
x = rand(10^6)
@time f(identity, x)
end
end
run (generic function with 1 method)
julia> run()
0.003013 seconds (3.17 k allocations: 170.994 KiB, 99.51% compilation time)
0.000002 seconds
julia> run()
0.000009 seconds
0.000005 seconds
This is actually the performance tip to be considered here (a tricky one, I learnt this the hard way as well):
https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing