Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Significant method invalidations for in with Julia 1.11 #147

Open
amilsted opened this issue Oct 9, 2024 · 4 comments
Open

Significant method invalidations for in with Julia 1.11 #147

amilsted opened this issue Oct 9, 2024 · 4 comments

Comments

@amilsted
Copy link

amilsted commented Oct 9, 2024

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.

@andyferris
Copy link
Owner

Interesting.

Can you write down how to reproduce that output?

@amilsted
Copy link
Author

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.

@serenity4
Copy link
Contributor

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?

@amilsted
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants