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.