Potential performance regressions in Julia 1.8 for special un-precompiled type dispatches and how to fix them

Okay, so I went a bit invalidation hunting this morning:

  • Static.jl invalidates quite a lot, see
    fix invalidations in logging by ranocha · Pull Request #46481 · JuliaLang/julia · GitHub,
    fix invalidations for Dicts from Static.jl by ranocha · Pull Request #46490 · JuliaLang/julia · GitHub,
    fix invalidations in sort! from Static.jl by ranocha · Pull Request #46491 · JuliaLang/julia · GitHub,
    fix invalidations of `isinf` from Static.jl by ranocha · Pull Request #46493 · JuliaLang/julia · GitHub,
    fix invalidations in REPLCompletions from Static.jl by ranocha · Pull Request #46494 · JuliaLang/julia · GitHub,
    fix invalidations from Static.jl by ranocha · Pull Request #140 · JuliaIO/Tar.jl · GitHub,
    fix API invalidations from Static.jl by ranocha · Pull Request #3179 · JuliaLang/Pkg.jl · GitHub
  • Unrolled.jl invalidates a bunch of stuff, see Unrolled.jl invalidates quite a lot · Issue #12 · cstjean/Unrolled.jl · GitHub
  • HDF5.jl invalidates a bunch of stuff in the REPL: hopefully fix invalidations of REPL from HDF5.jl by ranocha · Pull Request #46486 · JuliaLang/julia · GitHub
  • ChainRulesCore.jl invalidates a bunch of stuff, see Invalidations from ChainRulesCore Tangent overload on Tail · Issue #576 · JuliaDiff/ChainRulesCore.jl · GitHub
  • FixedPointNumbers.jl invalidates quite a bit, in particular from LoopVectorization calling sum(::Vector{Any})
    inserting reduce_first(::typeof(Base.add_sum), x::FixedPointNumbers.FixedPoint) in FixedPointNumbers at ~/.julia/packages/FixedPointNumbers/HAGk2/src/FixedPointNumbers.jl:295 invalidated:
      backedges: 1: superseding reduce_first(::typeof(Base.add_sum), x) in Base at reduce.jl:394 with MethodInstance for Base.reduce_first(::typeof(Base.add_sum), ::Any) (309 children)
    
  • ArrayInterface.jl invalidates parts of Tar.jl: hopefully fix invalidations from ArrayInterface.jl by ranocha · Pull Request #138 · JuliaIO/Tar.jl · GitHub, hopefully fix more invalidations by ranocha · Pull Request #139 · JuliaIO/Tar.jl · GitHub
  • OrderedCollections.jl invalidates quite a bit
    inserting convert(::Type{OrderedCollections.OrderedDict{K, V}}, d::OrderedCollections.OrderedDict{K, V}) where {K, V} in OrderedCollections at ~/.julia/packages/OrderedCollections/PRayh/src/ordered_dict.jl:110 invalidated:
     backedges: 1: superseding convert(::Type{T}, x::AbstractDict) where T<:AbstractDict in Base at abstractdict.jl:561 with MethodInstance for convert(::Type, ::AbstractDict) (134 children)
    
  • LoopVectorization.jl invalidates some code in HDF5.jl and indexing:
    inserting convert(::Type{T}, i::LoopVectorization.UpperBoundedInteger) where T<:Number in LoopVectorization at /home/hendrik/.julia/packages/LoopVectorization/e7fJe/src/reconstruct_loopset.jl:25 invalidated:
     backedges: 1: superseding convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 with MethodInstance for convert(::Type{UInt64}, ::Integer) (3 children)
                2: superseding convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 with MethodInstance for convert(::Type{Int64}, ::Integer) (17 children)
                3: superseding convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 with MethodInstance for convert(::Type{Int32}, ::Integer) (99 children)
     17 mt_cache
    
  • Geometry basics also invalidates code in HDF5.jl etc.
    inserting convert(::Type{IT}, x::GeometryBasics.OffsetInteger) where IT<:Integer in GeometryBasics at /home/hendrik/.julia/packages/GeometryBasics/5Sb5M/src/offsetintegers.jl:40 invalidated:
     mt_backedges: 1: signature convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 (formerly convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7) triggered MethodInstance for Colors._precompile_() (1 children)
                   2: signature convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 (formerly convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7) triggered MethodInstance for parse(::Type{ColorTypes.RGB{FixedPointNumbers.N0f8}}, ::String) (1 children)
                   3: signature convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 (formerly convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7) triggered MethodInstance for Colors._parse_colorant(::String) (1 children)
     backedges: 1: superseding convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 with MethodInstance for convert(::Type{Int64}, ::Integer) (9 children)
                2: superseding convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7 with MethodInstance for convert(::Type{Int32}, ::Integer) (91 children)
    
  • ForwardDiff.jl invalidates some string code: fix type instability/invalidations from `nextind` by ranocha · Pull Request #46489 · JuliaLang/julia · GitHub
  • StaticArrays.jl also invalidates quite a bit, e.g.,
    inserting similar(::Type{A}, shape::Union{Tuple{SOneTo, Vararg{Union{Integer, Base.OneTo, SOneTo}}}, Tuple{Union{Integer, Base.OneTo}, SOneTo, Vararg{Union{Integer, Base.OneTo, SOneTo}}}, Tuple{Union{Integer, Base.OneTo}, Union{Integer, Base.OneTo}, SOneTo, Vararg{Union{Integer, Base.OneTo, SOneTo}}}}) where A<:AbstractArray in StaticArrays at ~/.julia/packages/StaticArrays/68nRv/src/abstractarray.jl:156 invalidated:
     mt_backedges: 1: signature Tuple{typeof(similar), Type{Array{Union{Int64, Symbol}, _A}} where _A, Tuple{Union{Integer, AbstractUnitRange}}} triggered MethodInstance for similar(::Type{Array{Union{Int64, Symbol}, _A}}, ::Union{Integer, AbstractUnitRange}) where _A (0 children)
                   2: signature Tuple{typeof(similar), Type{Array{Union{Int64, Symbol}, _A}} where _A, Any} triggered MethodInstance for Base._array_for(::Type{Union{Int64, Symbol}}, ::Base.HasShape, ::Any) (0 children)
                   3: signature Tuple{typeof(similar), Type{Array{Any, _A}} where _A, Tuple{Union{Integer, AbstractUnitRange}}} triggered MethodInstance for similar(::Type{Array{Any, _A}}, ::Union{Integer, AbstractUnitRange}) where _A (0 children)
                   4: signature Tuple{typeof(similar), Type{Array{Any, _A}} where _A, Any} triggered MethodInstance for Base._array_for(::Type{Any}, ::Base.HasShape, ::Any) (0 children)
                   5: signature Tuple{typeof(similar), Type{Array{Base.PkgId, _A}} where _A, Tuple{Union{Integer, AbstractUnitRange}}} triggered MethodInstance for similar(::Type{Array{Base.PkgId, _A}}, ::Union{Integer, AbstractUnitRange}) where _A (0 children)
                   6: signature Tuple{typeof(similar), Type{Array{Base.PkgId, _A}} where _A, Any} triggered MethodInstance for Base._array_for(::Type{Base.PkgId}, ::Base.HasShape, ::Any) (0 children)
                   7: signature Tuple{typeof(similar), Type{Array{Union{Int64, Symbol}, _A}} where _A, Tuple{Union{Integer, AbstractUnitRange}}} triggered MethodInstance for similar(::Type{Array{Union{Int64, Symbol}, _A}}, ::Tuple{Union{Integer, Base.OneTo}}) where _A (9 children)
                   8: signature Tuple{typeof(similar), Type{Array{Base.PkgId, _A}} where _A, Tuple{Union{Integer, AbstractUnitRange}}} triggered MethodInstance for similar(::Type{Array{Base.PkgId, _A}}, ::Tuple{Union{Integer, Base.OneTo}}) where _A (9 children)
                   9: signature Tuple{typeof(similar), Type{Array{Any, _A}} where _A, Tuple{Union{Integer, AbstractUnitRange}}} triggered MethodInstance for similar(::Type{Array{Any, _A}}, ::Tuple{Union{Integer, Base.OneTo}}) where _A (136 children)
    
  • There are of course more invalidations, but they seem to be less severe, e.g.,
    hopefully fix invalidations in API from AbstractFFTs by ranocha · Pull Request #3180 · JuliaLang/Pkg.jl · GitHub

However, I would have expected that these invalidations happen also with Julia v1.7 - or do I miss something?

14 Likes