You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue summarizes the invalidation and TTFX (time-to-first-execution) improvement work across the SciML ecosystem from February to April 2026. It documents what was measured, what was fixed, what remains, and provides reproducible benchmarks.
All measurements use Julia 1.11.9 on Linux x86_64, using SnoopCompile/SnoopCompileCore for invalidation analysis and @elapsed for TTFX.
OrdinaryDiffEqCore Invalidations: Three Eras
Since OrdinaryDiffEqBDF can't be loaded against old registry versions (NonlinearSolve compat breakage), the cleanest comparison uses OrdinaryDiffEqCore — which contains the core dependency chain (Static, Polyester, FillArrays, DataStructures, etc.) without the NonlinearSolve complications.
Era 1: Feb 2026 (OrdinaryDiffEqCore v3.10, FillArrays + Static + Polyester)
Package
Invalidations
Root Cause
Static
137
convert(::Type{T<:Number}, ::StaticInt/Bool/Float64) — 95 children. any(::Tuple{StaticBool...}) — 31 children. Type piracy on broad Base types.
DataStructures
58
iterate on SwissDict (33 children), issubset on SortedSet (12)
FillArrays
30
print_matrix_row for FillArrays union types supersedes Base method — 25 children
SciMLBase
7
Moshi.Data variants
CloseOpenIntervals
5
Brought in by Static chain
Total
237
17 trees
Era 2: Apr 2026 registered (OrdinaryDiffEqCore v3.27, Static + Polyester, no FillArrays)
Package
Invalidations
Root Cause
Static
137
Same as Era 1 (identical Static.jl version)
DataStructures
59
Same as before (+1 from version change)
SciMLBase
7
Moshi.Data variants
CloseOpenIntervals
5
Same as before
Total
208
14 trees
FillArrays was removed between these eras, dropping 30 invalidations (237 → 208, but DataStructures went up by 1).
Era 3: v7 branch (no Polyester, no Static, no FillArrays)
Package
Invalidations
Root Cause
DataStructures
58
Same as always
SciMLBase
7
Moshi.Data variants (will go away with Moshi removal from SciMLBase)
Total
65
5 trees
Summary: 237 → 208 → 65 invalidated methods (73% reduction from Feb to v7 branch)
Full OrdinaryDiffEqBDF Stack: Invalidation Breakdown (Era 2, registered)
Loading the full BDF solver stack (which adds NonlinearSolve, ForwardDiff, StaticArrays, etc.) produces 2,442 total invalidated methods across 60 trees:
Package
Invalidations
%
Root Cause
Static.jl
732
30%
ifelse(::Static.False/True, x, y) — type piracy on ifelse(::Any, ::Any, ::Any) invalidates max, all ForwardDiff Jacobian computations, NonlinearSolve trust region. 261 children each for the two ifelse trees. Also convert(::Type{T<:Number}, ::StaticInt) (95 children).
Polyester.jl — removed from OrdinaryDiffEqCore and all 13 subpackages (Remove Polyester.jl dependency to eliminate Static.jl invalidations #3336). @threaded PolyesterThreads() falls back to Threads.@threads :static (equivalent for 2-4 iteration counts). Eliminated entire 11-package transitive chain.
Remaining invalidation sources in full BDF stack (~1,650 estimated after Polyester removal)
Package
Est. Invalidations
Actionable?
StaticArrays
~480
Hard — real dependency (SVector, MVector used everywhere). convert(::Type{Array{T,N}}, ::SizedArray) is the root. Upstream fix needed.
DataStructures
~225
Moderate — only BinaryHeap/FasterForward used. Could vendor those or use lighter dep.
NonlinearSolve stack
~330
Extension loading — inherent to mechanism
DiffEqBase
~161
Some may be addressable
SparseMatrixColorings exts
~254
Extension loading — inherent
ForwardDiff
~48
Likely inherent
Moshi/SciMLBase
~7
Will be eliminated when Moshi removal propagates
Open questions
Can DataStructures be replaced with a lighter dependency (just BinaryHeap)?
Can StaticArrays convert methods be made narrower upstream?
Is there a way to reduce extension-loading invalidation cascades (NonlinearSolve, SparseMatrixColorings)?
Reproducing These Measurements
Invalidation analysis script
using SnoopCompileCore
invalidations =@snoop_invalidationsbeginusing OrdinaryDiffEqBDF # or OrdinaryDiffEqCore for smaller scopeendusing SnoopCompile
trees = SnoopCompile.invalidation_trees(invalidations)
sort!(trees, by=t->SnoopCompile.countchildren(t), rev=true)
pkg_counts =Dict{String,Int}()
for tree in trees
pkg =string(Base.moduleroot(tree.method.module))
pkg_counts[pkg] =get(pkg_counts, pkg, 0) + SnoopCompile.countchildren(tree)
endfor (pkg, count) insort(collect(pkg_counts), by=x->x[2], rev=true)
println("$pkg: $count")
endprintln("Total: ", sum(SnoopCompile.countchildren(t) for t in trees; init=0))
Overview
This issue summarizes the invalidation and TTFX (time-to-first-execution) improvement work across the SciML ecosystem from February to April 2026. It documents what was measured, what was fixed, what remains, and provides reproducible benchmarks.
All measurements use Julia 1.11.9 on Linux x86_64, using
SnoopCompile/SnoopCompileCorefor invalidation analysis and@elapsedfor TTFX.OrdinaryDiffEqCore Invalidations: Three Eras
Since OrdinaryDiffEqBDF can't be loaded against old registry versions (NonlinearSolve compat breakage), the cleanest comparison uses OrdinaryDiffEqCore — which contains the core dependency chain (Static, Polyester, FillArrays, DataStructures, etc.) without the NonlinearSolve complications.
Era 1: Feb 2026 (OrdinaryDiffEqCore v3.10, FillArrays + Static + Polyester)
convert(::Type{T<:Number}, ::StaticInt/Bool/Float64)— 95 children.any(::Tuple{StaticBool...})— 31 children. Type piracy on broad Base types.iterateon SwissDict (33 children),issubseton SortedSet (12)print_matrix_rowfor FillArrays union types supersedes Base method — 25 childrenvariantsEra 2: Apr 2026 registered (OrdinaryDiffEqCore v3.27, Static + Polyester, no FillArrays)
variantsFillArrays was removed between these eras, dropping 30 invalidations (237 → 208, but DataStructures went up by 1).
Era 3: v7 branch (no Polyester, no Static, no FillArrays)
variants(will go away with Moshi removal from SciMLBase)Summary: 237 → 208 → 65 invalidated methods (73% reduction from Feb to v7 branch)
Full OrdinaryDiffEqBDF Stack: Invalidation Breakdown (Era 2, registered)
Loading the full BDF solver stack (which adds NonlinearSolve, ForwardDiff, StaticArrays, etc.) produces 2,442 total invalidated methods across 60 trees:
ifelse(::Static.False/True, x, y)— type piracy onifelse(::Any, ::Any, ::Any)invalidatesmax, all ForwardDiff Jacobian computations, NonlinearSolve trust region. 261 children each for the twoifelsetrees. Alsoconvert(::Type{T<:Number}, ::StaticInt)(95 children).convert(::Type{Array{T,N}}, ::SizedArray)supersedes Base'sconvert(::Type{T}, ::AbstractArray), invalidating all compiledVector{Float64}conversionsis_extension_loaded(::Val{:SparseMatrixColorings})cascadingThe dependency chains that were eliminated
Polyester.jl → Static.jl chain (~11 packages removed by #3336):
FillArrays (removed between Era 1 and Era 2):
print_matrix_rowfor FillArrays union types superseded Base's method — 25 children in CoreTTFX Benchmarks (Julia 1.11.9, 3 runs each, pre-compiled)
OrdinaryDiffEqBDF: Lorenz problem
using OrdinaryDiffEqBDFsolve(prob, FBDF())solve(prob, QNDF())What Was Fixed
Dependency removal
@threaded PolyesterThreads()falls back toThreads.@threads :static(equivalent for 2-4 iteration counts). Eliminated entire 11-package transitive chain.Precompile workloads
calculate_residuals: 0.14s → 0.0002s (~700x)ODE_DEFAULT_NORM: 0.017s → 0.00002s (~850x)ODE_DEFAULT_UNSTABLE_CHECK: 8.7ms → 0.003ms (2900x)Invalidation fixes
promote_fto prevent cascadeSciMLBase improvements
@datamacro was 21% of precompile time. Replaced with plain Julia: 3731ms → 0.1ms. SciMLBase precompilation: 17.7s → 13.6s (23% reduction)What Remains / Future Work
Remaining invalidation sources in full BDF stack (~1,650 estimated after Polyester removal)
convert(::Type{Array{T,N}}, ::SizedArray)is the root. Upstream fix needed.BinaryHeap/FasterForwardused. Could vendor those or use lighter dep.Open questions
convertmethods be made narrower upstream?Reproducing These Measurements
Invalidation analysis script
TTFX benchmark script
Related PRs and Issues
OrdinaryDiffEq.jl
DiffEqBase.jl
SciMLBase.jl
DifferentialEquations.jl