julia> f1 = function (x)
x/2
end
#3 (generic function with 1 method)
julia> function f1_2(x)
x/2
end
f1_2 (generic function with 1 method)
julia> f2 = function (x)
x
end
#5 (generic function with 1 method)
julia> function f2_2(x)
x
end
f2_2 (generic function with 1 method)
julia> using BenchmarkTools
julia> @benchmark f1(0.1)
BenchmarkTools.Trial: 10000 samples with 999 evaluations.
Range (min β¦ max): 16.517 ns β¦ 360.561 ns β GC (min β¦ max): 0.00% β¦ 90.23%
Time (median): 19.019 ns β GC (median): 0.00%
Time (mean Β± Ο): 20.266 ns Β± 9.995 ns β GC (mean Β± Ο): 0.44% Β± 1.54%
β β
ββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
16.5 ns Histogram: frequency by time 34.9 ns <
Memory estimate: 16 bytes, allocs estimate: 1.
julia> @benchmark f1_2(0.1)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
Range (min β¦ max): 0.800 ns β¦ 237.800 ns β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 0.800 ns β GC (median): 0.00%
Time (mean Β± Ο): 0.904 ns Β± 3.317 ns β GC (mean Β± Ο): 0.00% Β± 0.00%
β β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
0.8 ns Histogram: log(frequency) by time 1.9 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
julia> @benchmark f2(0.1)
BenchmarkTools.Trial: 10000 samples with 999 evaluations.
Range (min β¦ max): 11.712 ns β¦ 1.559 ΞΌs β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 13.614 ns β GC (median): 0.00%
Time (mean Β± Ο): 15.054 ns Β± 19.157 ns β GC (mean Β± Ο): 0.00% Β± 0.00%
ββ ββ
ββββββββ βββ ββββββββββββββββββββββββββββββββββββββββββββββββ β
11.7 ns Histogram: frequency by time 27.8 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
julia> @benchmark f2_2(0.1)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
Range (min β¦ max): 0.800 ns β¦ 277.500 ns β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 0.800 ns β GC (median): 0.00%
Time (mean Β± Ο): 0.917 ns Β± 3.086 ns β GC (mean Β± Ο): 0.00% Β± 0.00%
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
0.8 ns Histogram: frequency by time 1 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
Even though all functions are type-stable, the anonymous versions are drastically slower than the non-anonymous ones. Arenβt they supposed to be as generic as the latter?
BTW for both Julia 1.9.4 and 1.10.0 on my local machine, the same issue occurs.
Hence, if I have to generate functions on the fly (which is why I want to use anonymous functions), how can I achieve the same performance as the non-anonymous function versions, assuming I can ensure type stability?
Thanks for the reply! This makes sense to me now. Even though the anonymous function has a specific type, when assigned to a global variable f1 or f2, these variables are not type-stable because, unlike the function name for non-anonymous functions, they can be reassigned with other types of values.
Based on this understanding, I interpolated the value of f1 before running the benchmark, and they became as performant as the non-anonymous counterparts: