ModelingToolkit.jl
ModelingToolkit.jl copied to clipboard
Indexing solution with symbolic array is slow
using ModelingToolkit, OrdinaryDiffEq
@variables t u(t)[1:10] = 1
u = collect(u)
eqs = Differential(t).(u) .~ (1:length(u))
@named sys = ODESystem(eqs,t,u,[]; tspan=(0, 10))
prob = ODEProblem(sys)
sol = solve(prob, Tsit5(), tstops=range(prob.tspan...; length=10000))
using BenchmarkTools
@btime getindex($sol, $u);
# 1.649 s (12584906 allocations: 1.47 GiB)
Seems to scale roughly linearly with the length of the solution
sol = solve(prob, Tsit5(), tstops=range(prob.tspan...; length=100))
@btime getindex($sol, $u);
# 15.070 ms (124909 allocations: 15.01 MiB)
Indexing the solution with 10 separate scalar symbols is reasonably fast. Not exactly a 1:1 comparison, but this should give a reasonable order of magnitude for the expected speed.
sol = solve(prob, Tsit5(), tstops=range(prob.tspan...; length=10000))
@btime getindex.($(Ref(sol)), $u);
# 312.833 μs (1259 allocations: 932.17 KiB)
I think this is because of sym_to_index, which is a search through the states of the system, if there is no ordering here this would have to be an O(n) operation.
I've noticed that unsurprisingly a hashmap (Dict) indexed with symbols is faster for even a low number of states, though if you try to index with more complex expressions this becomes a trade off at low n as the hashing cost increases, we should probably be creating index maps to levarage this.
I add a sym_map that can do this in #2071, once this is merged we can move to using this by default.
Fixed with new SII tools, or repeat of the SII issue https://github.com/SciML/ModelingToolkit.jl/issues/2338