For demonstration of this problem, create a tuple of two matrices, one with Float64
and the other with Int64
as entries:
julia> VERSION
v"0.6.3-pre.0"
julia> mats = (rand(3,3), rand(Int64,3,3));
Also create a tuple of Float64
and Int64
, which we will set as the (1,1) entries of the above-created two matrices:
julia> vals = (0.0, 0);
Now, let’s set the entries by broadcasting setindex!
over the tuples. The performance is pretty good with only one allocation:
julia> using BenchmarkTools
julia> @btime setindex!.($mats, $vals, 1, 1);
10.381 ns (1 allocation: 32 bytes)
However, if if I pass the indices as a splatted tuple, suddenly the performance degrades significantly with 10 allocations:
julia> @btime setindex!.($mats, $vals, (1,1)...);
394.860 ns (10 allocations: 288 bytes)
Why is this happening?
Note 1. This performance degradation does not happen if mats
is a tuple of matrices of the same eltype:
julia> mats = (rand(3,3), rand(3,3));
julia> vals = (0.0, 0.0);
julia> @btime setindex!.($mats, $vals, (1,1)...);
10.921 ns (1 allocation: 32 bytes)
Because the performance degradation happens when mats
is a tuple of inhomogeneous types, I guess this problem has the same origin as this issue. However, then I’m not sure why the splat matters here.
Note 2. The situation is not much different in Julia 0.7.