Hello everyone,
I was trying to write some generic code in which users can provide indices either as Ints (in 1D) or as tuples of Ints (in 2D/3D). To interface with functions like getindex
, my solution was to splat the indices.
Splatting a tuple has no runtime cost, since the compiler knows the size of the tuple. I would have expected the same to hold for integers, but I noticed a 100x runtime increase.
using BenchmarkTools
a = [1 2 3 4; 5 6 7 8]
i = (1, 2)
@btime getindex($a, ($i)[1], ($i)[2])
@btime getindex($a, ($i)...)
#=
2.367 ns (0 allocations: 0 bytes)
2.073 ns (0 allocations: 0 bytes)
=#
a = [1, 2, 3, 4, 5, 6]
i = 3
@btime getindex($a, $i)
@btime getindex($a, ($i)...)
#=
1.781 ns (0 allocations: 0 bytes)
100.659 ns (2 allocations: 32 bytes)
=#
My guess is that the same compiler optimization could be used for Ints and Tuples, but the developers did not take the time to implement it for Ints since it has little practical use. Is that correct or am I missing something?
Anyway, it is always possible to go around this limitation by converting the Int to a one-element Tuple:
i = (3,)
@btime getindex($a, ($i)[1])
@btime getindex($a, ($i)...)
#=
1.781 ns (0 allocations: 0 bytes)
1.782 ns (0 allocations: 0 bytes)
=#
Related discussion: Concerns about splatting