Summary
Loading GeometryBasics into a session that already has ModelingToolkit loaded invalidates
11,182 precompiled method instances and makes the first mtkcompile call take
15.8 s instead of 2.2 s — a 7x slowdown in a script that never uses a geometric type.
Most users meet this indirectly: Makie depends on GeometryBasics, so any Makie-based
plotting next to ModelingToolkit pays this cost on the first model build.
MWE
# mwe.jl
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
if get(ENV, "LOAD_GB", "0") == "1"
@eval using GeometryBasics # <-- the only difference
end
@variables x(t)=1.0 y(t)=0.0
@named sys = System([D(x) ~ y, D(y) ~ -x], t)
t0 = time(); mtkcompile(sys); println("mtkcompile: ", round(time()-t0, digits=2), " s")
$ julia --startup-file=no --project=. mwe.jl
mtkcompile: 2.22 s
$ LOAD_GB=1 julia --startup-file=no --project=. mwe.jl
mtkcompile: 15.80 s
As a control, loading a package of comparable size that does not add methods to Base
generics (using LaTeXStrings) leaves the time unchanged at 2.23 s, so this is not the
general cost of loading a package.
Attribution
using SnoopCompileCore
using ModelingToolkit
invs = @snoop_invalidations using GeometryBasics;
using SnoopCompile
length(uinvalidated(invs)) # 11182, from 169 culprit methods
Ranked by countchildren:
| children |
method |
| 19704 |
convert(::Type{O}, x::Integer) where O<:OffsetInteger — src/offsetintegers.jl:55 |
| 6542 |
convert(::Type{IT}, x::OffsetInteger) where IT<:Integer — src/offsetintegers.jl:53 |
| 5881 |
>=(x::OffsetInteger, y::OffsetInteger) — src/offsetintegers.jl:81 |
| 876 |
promote_rule(::Type{OffsetInteger{O1,T1}}, ::Type{OffsetInteger{O2,T2}}) where {O1,O2,T1<:Integer,T2<:Integer} — src/offsetintegers.jl:87 |
| 566 |
promote_rule(::Type{IT}, ::Type{<:OffsetInteger}) where IT<:Integer — src/offsetintegers.jl:85 |
| 412 |
broadcasted(f, a::AbstractArray{T}, b::NgonFace) where T<:NgonFace — src/fixed_arrays.jl:124 |
Nearly all of it comes from OffsetInteger. convert(::Type{IT}, ::OffsetInteger) where IT<:Integer in particular is a method on Base.convert whose second argument carries the
package's own type but whose first is a broad Type{IT<:Integer}, which discards inference
results in already-loaded packages that call convert(::Type{<:Integer}, x) on
non-concrete argument types.
Question
Is OffsetInteger still load-bearing, and if so, is there room to narrow these signatures?
I am mostly filing this for the record, since the measured impact is large and I could not
find an existing issue about it. Happy to run further measurements if that helps.
Versions
Julia 1.12.7 (Linux, x86_64), GeometryBasics 0.5.12, ModelingToolkit 11.17.0,
SnoopCompile 3.2.9.
Summary
Loading GeometryBasics into a session that already has ModelingToolkit loaded invalidates
11,182 precompiled method instances and makes the first
mtkcompilecall take15.8 s instead of 2.2 s — a 7x slowdown in a script that never uses a geometric type.
Most users meet this indirectly: Makie depends on GeometryBasics, so any Makie-based
plotting next to ModelingToolkit pays this cost on the first model build.
MWE
As a control, loading a package of comparable size that does not add methods to Base
generics (
using LaTeXStrings) leaves the time unchanged at 2.23 s, so this is not thegeneral cost of loading a package.
Attribution
Ranked by
countchildren:convert(::Type{O}, x::Integer) where O<:OffsetInteger—src/offsetintegers.jl:55convert(::Type{IT}, x::OffsetInteger) where IT<:Integer—src/offsetintegers.jl:53>=(x::OffsetInteger, y::OffsetInteger)—src/offsetintegers.jl:81promote_rule(::Type{OffsetInteger{O1,T1}}, ::Type{OffsetInteger{O2,T2}}) where {O1,O2,T1<:Integer,T2<:Integer}—src/offsetintegers.jl:87promote_rule(::Type{IT}, ::Type{<:OffsetInteger}) where IT<:Integer—src/offsetintegers.jl:85broadcasted(f, a::AbstractArray{T}, b::NgonFace) where T<:NgonFace—src/fixed_arrays.jl:124Nearly all of it comes from
OffsetInteger.convert(::Type{IT}, ::OffsetInteger) where IT<:Integerin particular is a method onBase.convertwhose second argument carries thepackage's own type but whose first is a broad
Type{IT<:Integer}, which discards inferenceresults in already-loaded packages that call
convert(::Type{<:Integer}, x)onnon-concrete argument types.
Question
Is
OffsetIntegerstill load-bearing, and if so, is there room to narrow these signatures?I am mostly filing this for the record, since the measured impact is large and I could not
find an existing issue about it. Happy to run further measurements if that helps.
Versions
Julia 1.12.7 (Linux, x86_64), GeometryBasics 0.5.12, ModelingToolkit 11.17.0,
SnoopCompile 3.2.9.