-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
Can we improve inference of the following snippet?
julia> code_warntype(keys, (Dict{String},))
MethodInstance for keys(::Dict{String})
from keys(a::AbstractDict) in Base at abstractdict.jl:105
Arguments
#self#::Core.Const(keys)
a::Dict{String}
Body::Base.KeySet{String, _A} where _A<:(AbstractDict{String})
1 ─ %1 = Base.KeySet(a)::Base.KeySet{String, _A} where _A<:(AbstractDict{String})
└── return %1I am using Julia v1.8.2. I think the return type should be inferred more concretely, with _A<:(Dict{String}) and not _A<:(AbstractDict{String}). This would fix a big amount of invalidations, e.g.,
julia> import Pkg; Pkg.activate(temp=true); Pkg.add("DataStructures")
julia> using SnoopCompileCore; invalidations = @snoopr(using DataStructures); using SnoopCompile
julia> length(uinvalidated(invalidations))
482
julia> trees = invalidation_trees(invalidations)
...
inserting iterate(v::Union{Base.KeySet{<:Any, <:SwissDict}, Base.ValueIterator{<:SwissDict}}, state) in DataStructures at ~/.julia/packages/DataStructures/59MD0/src/swiss_dict.jl:646 invalidated:
...
julia> ascend(root)
Choose a call for analysis (q to quit):
iterate(::Base.KeySet{String, _A} where _A<:(Dict{String}), ::Int64)
iterate(::T) where T<:(Base.KeySet{String, _A} where _A<:(Dict{String}))
copyto!(::Vector{String}, ::Base.KeySet{String, _A} where _A<:(AbstractDict{String}))
_collect(::UnitRange{Int64}, ::Base.KeySet{String, _A} where _A<:(AbstractDict{String}), ::Base.HasElt
collect(::Base.KeySet{String, _A} where _A<:(AbstractDict{String}))
> #_print#10(::Int64, ::Bool, ::Bool, ::Function, ::typeof(TOML.Internals.Printer._print), ::Nothing
...The relevant part is
julia/stdlib/TOML/src/print.jl
Lines 101 to 104 in d498d36
| akeys = keys(a) | |
| if sorted | |
| akeys = sort!(collect(akeys); by) | |
| end |
In the first line, akeys is inferred as Base.KeySet{String, _A} where _A<:(AbstractDict{String}). If inference gave Dict{String} here, the invalidations would be gone. I also don't see a nice way to fix these invalidations since _print accepts a::AbstractDict and some comments suggest that AbstractDict is really required, not just Dict
julia/stdlib/TOML/src/print.jl
Line 146 in d498d36
| # Use runtime dispatch here since the type of value seems not to be enforced other than as AbstractDict |