Force specialization on varargs when the arguments are not all of the same concrete type

The manual page on Performance Tips (https://github.com/JuliaLang/julia/blob/master/doc/src/manual/performance-tips.md) says:

This will not specialize:

f_vararg(x::Int...) = tuple(x...)

but this will:

g_vararg(x::Vararg{Int, N}) where {N} = tuple(x...)

Unfortunately, this only works if all of the arguments are of the same concrete type.

Is there a way for me to force specialization on varargs when the arguments are not necessarily all of the same concrete type?

h_vararg(x::Vararg{Any, N}) where {N} = tuple(x...) seems to work

julia> h_vararg(1,2.0,:three,"four")
(1, 2.0, :three, "four")

julia> (@which h_vararg(1,2.0,:three,"four")).specializations
Core.TypeMapEntry(nothing, Tuple{typeof(h_vararg),Int64,Float64,Symbol,String}, nothing, svec(), 0x0000000000000001, 0xffffffffffffffff, MethodInstance for h_vararg(::Int64, ::Float64, ::Symbol, ::String), true, true, false)
1 Like

I notice that both of the following seem to work:

h_vararg(x::Vararg{Any, N}) where {N} = tuple(x...)
h_vararg(x::Vararg{<:Any, N}) where {N} = tuple(x...)

Do you think that there is any difference between the two? Should one be preferred over the other?

Also, perhaps this should be added to the documentation?

https://github.com/JuliaLang/julia/pull/34796

1 Like

On a separate note, I have an analogous question about forcing specialization on keyword arguments:

I don’t know, but my guess is that they are equivalent:

julia> Tuple{Vararg{<:Any,3}}
Tuple{Any,Any,Any}

julia> Tuple{Vararg{Any,3}}
Tuple{Any,Any,Any}