I want to annotate a type-unstable variable with a type-parameter constraint to improve the chance of union splitting during compilation. In general, should I do Tuple of Union or Union of Tuple?
For example, which of the following struct is better, assuming T1 and T2 have different underlying data structures?
struct TofU{T1, T2}
a::NTuple{2, Union{T1, T2}}
end
struct UofT{T1, T2}
a::Union{Tuple{T1, T2}, Tuple{T2, T1}, NTuple{2, T1}, NTuple{2, T2}}
end
Note that for any given T1 and T2 (T1 != T2), though NTuple{2, Union{T1, T2}} and Union{Tuple{T1, T2}, Tuple{T2, T1}, NTuple{2, T1}, NTuple{2, T2}} represent two “equal” types, they are not identical (egal):
julia> T1 = Int
Int64
julia> T2 = Float64
Float64
julia> t1 = NTuple{2, Union{T1, T2}}
Tuple{Union{Float64, Int64}, Union{Float64, Int64}}
julia> t2 = Union{Tuple{T1, T2}, Tuple{T2, T1}, NTuple{2, T1}, NTuple{2, T2}}
Union{Tuple{Float64, Float64}, Tuple{Float64, Int64}, Tuple{Int64, Float64}, Tuple{Int64, Int64}}
julia> t1 == t2
true
julia> t1 === t2
false
Hence, I assume there is some non-negligible overhead difference in compilation or dispatch process.
Only unions of tuples participate in the union-splitting optimizations, so those tend to perform better.
1 Like