I regularly have a large number of arguments to carry around, where each of the arguments has a concrete type, but where the concrete types can be different (multiple dispatch). The arguments are typically more complicated than the ones in the code below. Other than the overhead of packing and unpacking elements into and out of S
, are there any gotchas with using S
over using separate arguments?
using UnPack, BenchmarkTools
function f( a :: Matrix{T1}, b :: Matrix{T2}, c :: Matrix{T3}, d :: Matrix{T4} ) where {T1<:Real,T2<:Real,T3<:Real,T4<:Real}
return a * b * c * d
end
struct S{A,B,C,D}
a :: A
b :: B
c :: C
d :: D
end
function g( s :: S{Matrix{T1},Matrix{T2},Matrix{T3},Matrix{T4}} ) where {T1<:Real,T2<:Real,T3<:Real,T4<:Real}
@unpack a,b,c,d = s
return a * b * c * d
end
function h( s :: S{Matrix{T1}} ) where {T1<:Real}
@unpack a,b,c,d = s
return a * b * c * d
end
function i( s :: S )
@unpack a,b,c,d = s
return a * b * c * d
end
@btime f(a,b,c,d) setup=( a = randn( 20, 3 ); b = rand(Int,3,50); c = randn(50,30); d = randn(30,100) )
@btime g( s ) setup=( s = S( randn( 20, 3 ), rand(Int,3,50), randn(50,30), randn(30,100) ) )
@btime h( s ) setup=( s = S( randn( 20, 3 ), rand(Int,3,50), randn(50,30), randn(30,100) ) )
@btime i( s ) setup=( s = S( randn( 20, 3 ), rand(Int,3,50), randn(50,30), randn(30,100) ) )