If you use tuples and the approach above, type stability will depend on some
cutoffs determined by the length of the tuples. For me, this cutoff is at
four elements in algorithms
.
julia> using BenchmarkTools
julia> A(x) = sin(x) ; B(x) = x^3 ; C(x) = log(x); D(x) = 2x; E(x) = exp(x);
julia> function my_calculation(algorithms, x)
return minimum(f(x) for f in algorithms)
end
julia> @benchmark my_calculation( $(Ref((A, B, C)))[], $(Ref(10))[] )
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 22.688 ns (0.00% GC)
median time: 22.724 ns (0.00% GC)
mean time: 22.989 ns (0.00% GC)
maximum time: 65.425 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 996
julia> @benchmark my_calculation( $(Ref((A, B, C, D, E)))[], $(Ref(10))[] )
BenchmarkTools.Trial:
memory estimate: 288 bytes
allocs estimate: 18
--------------
minimum time: 571.109 ns (0.00% GC)
median time: 580.388 ns (0.00% GC)
mean time: 609.541 ns (1.02% GC)
maximum time: 7.012 μs (89.64% GC)
--------------
samples: 10000
evals/sample: 183
To get type stability for more elements, you can use “lispy tuple programming”
similar to julia - Type stability for lists of closures - Stack Overflow.
julia> function my_calculation_lispy(algorithms::NTuple{N,Any}, x) where {N}
alg = first(algorithms)
remaining_algorithms = Base.tail(algorithms)
return min(alg(x), my_calculation_lispy(remaining_algorithms, x))
end
julia> function my_calculation_lispy(algorithms::Tuple{Any}, x)
return first(algorithms)(x)
end
julia> my_calculation_lispy( (A, B, C, D, E), 10) ≈ my_calculation( (A, B, C, D, E), 10)
true
julia> @benchmark my_calculation_lispy( $(Ref((A, B, C)))[], $(Ref(10))[] )
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 22.466 ns (0.00% GC)
median time: 22.520 ns (0.00% GC)
mean time: 22.991 ns (0.00% GC)
maximum time: 56.554 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 996
julia> @benchmark my_calculation_lispy( $(Ref((A, B, C, D, E)))[], $(Ref(10))[] )
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 42.918 ns (0.00% GC)
median time: 43.007 ns (0.00% GC)
mean time: 44.077 ns (0.00% GC)
maximum time: 123.421 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 990