Dictionaries.jl icon indicating copy to clipboard operation
Dictionaries.jl copied to clipboard

Significant method invalidations for `in` with Julia 1.11

Open amilsted opened this issue 1 year ago • 2 comments

I'm seeing the following SnoopCompile output:

 inserting in(inds::Dictionaries.ReverseIndices{I, Inds} where Inds<:Dictionaries.AbstractIndices{I}, i::I) where I @ Dictionaries ~/.julia/packages/Dictionaries/RaTRN/src/reverse.jl:7 invalidated:
   backedges:  1: superseding in(x, s::Set) @ Base set.jl:92 with MethodInstance for in(::Any, ::Set{T} where T<:Integer) (1 children)
               3: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::NTuple{5, Symbol}) (1 children)
               4: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{String, String, String, Nothing}) (1 children)
               5: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::NTuple{8, Symbol}) (1 children)
               6: superseding in(x, itr) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Array{String}) (1 children)
               7: superseding in(x, itr) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Base.Generator{I, DataFrames.var"#941#943"} where I<:(Base.Iterators.Filter{DataFrames.var"#942#944"})) (1 children)
              10: superseding in(k, v::Base.KeySet{<:Any, <:IdDict}) @ Base iddict.jl:182 with MethodInstance for in(::Any, ::Base.KeySet{Any, IdDict{Any, Nothing}}) (2 children)
              11: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{String, String, String}) (2 children)
              12: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{}) (2 children)
              13: superseding in(x, itr) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Vector{Any}) (2 children)
              14: superseding in(x, s::Set) @ Base set.jl:92 with MethodInstance for in(::Any, ::Set{<:Union{Missing, Integer}}) (3 children)
              15: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{Symbol, Symbol, Symbol}) (3 children)
              17: superseding in(key, v::Base.KeySet{<:Any, <:Dict}) @ Base dict.jl:549 with MethodInstance for in(::Any, ::Base.KeySet{String, Dict{String, Tuple{Any, Any}}}) (4 children)
              18: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{Symbol, Symbol}) (5 children)
              19: superseding in(x, itr) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::String) (7 children)
              20: superseding in(x, s::Set) @ Base set.jl:92 with MethodInstance for in(::Any, ::Set) (11 children)
              21: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{typeof(+), typeof(*)}) (13 children)
              22: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{Nothing, Bool}) (15 children)
              23: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{String, String}) (19 children)
              24: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{typeof(*), typeof(^)}) (20 children)
              25: superseding in(x, itr) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::BitSet) (26 children)
              26: superseding in(x, s::Set) @ Base set.jl:92 with MethodInstance for in(::Any, ::Set{Symbol}) (31 children)
              27: superseding in(x, itr::Tuple) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Tuple{typeof(+), typeof(*), typeof(^)}) (31 children)
              28: superseding in(x, s::IdSet) @ Base idset.jl:44 with MethodInstance for in(::Any, ::IdSet{Dict}) (41 children)
              29: superseding in(x, s::Set) @ Base set.jl:92 with MethodInstance for in(::Any, ::Set{Any}) (63 children)
              30: superseding in(x, itr) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Vector) (78 children)
              31: superseding in(x, itr) @ Base operators.jl:1302 with MethodInstance for in(::Any, ::Vector{Symbol}) (109 children)
              32: superseding in(x, s::IdSet) @ Base idset.jl:44 with MethodInstance for in(::Any, ::IdSet{Dict{String}}) (114 children)
              33: superseding in(k, v::Base.KeySet{<:Any, <:IdDict}) @ Base iddict.jl:182 with MethodInstance for in(::Any, ::Base.KeySet{Any, IdDict{Any, Any}}) (481 children)

Some lines removed. The last few seem particularly concerning.

amilsted avatar Oct 09 '24 22:10 amilsted

Interesting.

Can you write down how to reproduce that output?

andyferris avatar Oct 12 '24 05:10 andyferris

This was an entry in the invalidations data harvested using this tutorial.

I ran @snoop_invalidations using X, where X is a package that pulls in Dictionaries. Running it on using Dictionaries may (should?) give you similar data.

It looks like the problem is related to the base methods of in all accepting Any type for the first argument, whereas the Dictionaries method constrains the type of x.

amilsted avatar Oct 16 '24 17:10 amilsted

I just noticed these invalidations too, and see two ways to deal with this:

  • Avoid invalidations by using another function instead of extending Base.in (may not be appropriate if ReversedIndices are meant to be used and follow an interface on Base.in)
  • Recompile invalidations, as described in this tutorial where we surround the method with @recompile_invalidations begin ... #= method =# end using PrecompileTools.

Any thoughts/preferences?

serenity4 avatar Oct 27 '24 08:10 serenity4

Just wanted to add that the SciML packages depend on https://github.com/SciML/CommonWorldInvalidations.jl these days, which attempts to be "one place" where a bunch of invalidations are dealt with (it uses @recompile_invalidations). One path would be to try to add some methods there and have Dictionaries depend on it.

amilsted avatar Nov 26 '24 19:11 amilsted