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

Load time performance issue due to type pirating to deprecate methods in SciMLBase

Open vtjnash opened this issue 6 months ago • 4 comments

I modified julia to print out the cost of each new methods, in milliseconds, and this deprecation (200 ms) seemed to be responsible for a substantial fraction of the total load time of MTK (about 324 ms):

0.009292 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{uType, tType, isinplace, P, F, K} where K where F where P where isinplace where tType where uType})(ModelingToolkit.System, AbstractArray{T, N} where N where T, Any, Base.AbstractDict{K, V} where V where K)
0.025875 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, spec, isinplace, P, F, K} where K where F where P where isinplace})(ModelingToolkit.System, AbstractArray{var"#s322", N} where N where var"#s322"<:(Pair{A, B} where B where A), Any, Base.AbstractDict{K, V} where V where K) where {iip, spec}
183.124625 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, tType, isinplace, P, F, K} where K where F where P where isinplace where tType})(ModelingToolkit.System, AbstractArray{var"#s322", N} where N where var"#s322"<:(Pair{A, B} where B where A), Any, Base.AbstractDict{K, V} where V where K) where {iip}
0.019542 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{uType, tType, isinplace, P, F, K} where K where F where P where isinplace where tType where uType})(ModelingToolkit.System, AbstractArray{var"#s322", N} where N where var"#s322"<:(Pair{A, B} where B where A), Any, Base.AbstractDict{K, V} where V where K)
0.034000 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, spec, isinplace, P, F, K} where K where F where P where isinplace})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, AbstractArray{T, N} where N where T) where {iip, spec}
0.040291 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, tType, isinplace, P, F, K} where K where F where P where isinplace where tType})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, AbstractArray{T, N} where N where T) where {iip}
0.010333 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{uType, tType, isinplace, P, F, K} where K where F where P where isinplace where tType where uType})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, AbstractArray{T, N} where N where T)
0.031542 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, spec, isinplace, P, F, K} where K where F where P where isinplace})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, AbstractArray{var"#s324", N} where N where var"#s324"<:(Pair{A, B} where B where A)) where {iip, spec}
0.039208 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, tType, isinplace, P, F, K} where K where F where P where isinplace where tType})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, AbstractArray{var"#s324", N} where N where var"#s324"<:(Pair{A, B} where B where A)) where {iip}
0.009959 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{uType, tType, isinplace, P, F, K} where K where F where P where isinplace where tType where uType})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, AbstractArray{var"#s324", N} where N where var"#s324"<:(Pair{A, B} where B where A))
0.026292 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, spec, isinplace, P, F, K} where K where F where P where isinplace})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, Base.AbstractDict{K, V} where V where K) where {iip, spec}
0.037209 ModelingToolkit (::Type{SciMLBase.ImplicitDiscreteProblem{iip, tType, isinplace, P, F, K} where K where F where P where isinplace where tType})(ModelingToolkit.System, Base.AbstractDict{K, V} where V where K, Any, Base.AbstractDict{K, V} where V where K) where {iip}

It isn't usually the same one from run to run, but always at least one of them that seems catastrophic and the rest causing more subtle issues. In general, any time you define methods using a for loop you are going to pay an significant exponential cost for each iteration. If you want to avoid that, you must define the method once using a type-signature of Union instead, or better yet, use Any in any signature where you would consider having a Union or equivalently a for loop.

vtjnash avatar Jul 02 '25 20:07 vtjnash

@AayushSabharwal is there a way to simplify them? They are just the version with more arguments? they could use any?

ChrisRackauckas avatar Jul 03 '25 20:07 ChrisRackauckas

It's not piracy because of the system argument.

ChrisRackauckas avatar Jul 03 '25 21:07 ChrisRackauckas

In general, any time you define methods using a for loop you are going to pay an significant exponential cost for each iteration.

Out of curiosity, does for x in [...]; foo @eval(f(::$x) = ...) end somehow perform worse than @eval begin $([:(f(::$x)) for x in [...]]...) end? Maybe due to world age considerations? I'm surprised at the "exponential" part.

cstjean avatar Jul 04 '25 00:07 cstjean

Each method you create adds exponential load to the system. Do not create many methods with the same code (if avoidable) as they will each be treated separately as N items instead of as 1 item

vtjnash avatar Jul 04 '25 01:07 vtjnash