Open timholy opened 4 years ago
An alternative might be explicitly converting the pairs in the Dict
constructor like this:
julia> struct Dict2{K,V}
Dict2{K,V}(x::Pair...) where {K,V} = Dict{K,V}(map(p -> convert(Pair{K,V}, p), x)::Tuple{Vararg{Pair{K,V}}}...)
end
julia> code_typed(f2, ())
1-element Vector{Any}:
CodeInfo(
1 ─ %1 = %new(Pair{Symbol,Any}, :a, 1)::Pair{Symbol,Any}
│ %2 = %new(Pair{Symbol,Any}, :b, "hello")::Pair{Symbol,Any}
│ %3 = invoke Dict{Symbol,Any}(%1::Pair{Symbol,Any}, %2::Vararg{Pair{Symbol,Any},N} where N)::Dict{Symbol,Any}
└── return %3
) => Dict{Symbol,Any}
julia> @btime f()
216.752 ns (6 allocations: 672 bytes)
Dict{Symbol,Any} with 2 entries:
:a => 1
:b => "hello"
julia> @btime ft()
165.954 ns (6 allocations: 672 bytes)
Dict{Symbol,Any} with 2 entries:
:a => 1
:b => "hello"
julia> @btime f2()
159.693 ns (6 allocations: 672 bytes)
Dict{Symbol,Any} with 2 entries:
:a => 1
:b => "hello"
Although I don't know whether that would still be as fast if the pairs are not just constants.
is there any chance this is something that should just be done by the parser
No :smile:
Currently, the syntax
a => b
creates the narrowest typed-Pair fora
andb
. However, when this pair is being used to construct a heterogeneousDict
, this isn't exactly what you want: you'd prefer the pairs to be created from the outset with the Dict's key and value type:is not as nice (in terms of generated code) as
We could have a
@Dict
that performs this operation, but before implementing this, is there any chance this is something that should just be done by the parser?