Symbolics causing a lot of method invalidations
GlenHertz opened this issue · comments
Glen Hertz commented
using MyProject
went form 12 to 6 seconds by removing the Symbolics dependency. I did a SnoopCompile analysis and the top contributors were related to:
Lines 190 to 192 in 94e0dd0
I tried switching the order so the Base.isequal(::Symbolic, ::Symbolic) = false
definition was first hoping it wouldn't go into an ambiguous state but that didn't help.
I created a MWE with that seems to give me similar results to when it is in my project:
using SnoopCompile
invalidations = @snoopr begin
# Your code goes here!
using Symbolics # all that is needed
end;
trees = SnoopCompile.invalidation_trees(invalidations);
@show length(SnoopCompile.uinvalidated(invalidations)) # show 3500 total invalidations
show(trees[end]) # show the most invalidated method
show(trees[end-1]) # show the most invalidated method
show(trees[end-2]) # show the most invalidated method
# Count number of children (number of invalidations per invalidated method)
n_invalidations = map(trees) do methinvs
SnoopCompile.countchildren(methinvs)
end
import Plots
Plots.plot(
1:length(trees),
n_invalidations;
markershape=:circle,
xlabel="i-th method invalidation",
label="Number of children per method invalidations"
)
The one with the most invalidations is:
julia> show(trees[end]) # show the most invalidated method
inserting isequal(x, ::SymbolicUtils.Symbolic) @ SymbolicUtils ~/.julia/packages/SymbolicUtils/qulQp/src/types.jl:64 invalidated:
backedges: 1: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::Distributed.RRID, ::Any) (1 children)
2: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::Tuple{Module, String, Float64}, ::Any) (1 children)
3: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::WeakRef, ::Any) (2 children)
4: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::Type, ::Any) (5 children)
5: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::Distributed.Future, ::Any) (31 children)
6: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::Char, ::Any) (38 children)
7: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::String, ::Any) (577 children)
false
Next:
julia> show(trees[end-1])
inserting isequal(::SymbolicUtils.Symbolic, x) @ SymbolicUtils ~/.julia/packages/SymbolicUtils/qulQp/src/types.jl:63 invalidated:
mt_backedges: 1: signature isequal(x, y) @ Base operators.jl:133 (formerly isequal(x, y) @ Base operators.jl:133) triggered MethodInstance for ==(::WeakRef, ::Symbol) (0 children)
2: signature isequal(x, y) @ Base operators.jl:133 (formerly isequal(x, y) @ Base operators.jl:133) triggered MethodInstance for setindex!(::Dict, ::typeof(Latexify.mdtable), ::Symbol) (0 children)
3: signature isequal(x, y) @ Base operators.jl:133 (formerly isequal(x, y) @ Base operators.jl:133) triggered MethodInstance for setindex!(::Dict, ::typeof(Latexify._latexinline), ::Symbol) (0 children)
backedges: 1: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::Any, ::String) (46 children)
2: superseding isequal(x, y) @ Base operators.jl:133 with MethodInstance for isequal(::Any, ::Char) (224 children)
30 mt_cache
false
But in my project the output is about 5 times larger.