-
-
Notifications
You must be signed in to change notification settings - Fork 221
Get the performance of ArrayPartition up to that of Vector #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
These timings make use of SciML/DiffEqBase.jl@9276249 which helped a lot. |
New timings: using DiffEqBase, OrdinaryDiffEq, Base.Test, RecursiveArrayTools, DiffEqDevTools
using BenchmarkTools
u0 = zeros(100)
v0 = ones(100)
f1 = function (t,u,v,du)
du .= v
end
f2 = function (t,u,v,dv)
dv .= -u
end
function (::typeof(f2))(::Type{Val{:analytic}}, x, y0)
u0, v0 = y0
ArrayPartition(u0*cos(x) + v0*sin(x), -u0*sin(x) + v0*cos(x))
end
prob = DynamicalODEProblem(f1,f2,u0,v0,(0.0,5.0))
@benchmark solve(prob,RK4(),dt=1/2,adaptive=false,save_everystep=false) gives BenchmarkTools.Trial:
memory estimate: 90.83 KiB
allocs estimate: 637
--------------
minimum time: 137.588 μs (0.00% GC)
median time: 153.982 μs (0.00% GC)
mean time: 181.241 μs (5.89% GC)
maximum time: 3.434 ms (92.12% GC)
--------------
samples: 10000
evals/sample: 1 while function f(t,u,du)
uu = @view u[1:100]
v = @view u[101:end]
du[1:100] .= uu
du[101:200] .= v
end
u02 = [zeros(100);ones(100)]
tspan=(0.0,5.0)
prob = ODEProblem(f,u02,tspan)
@benchmark sol = solve(prob,RK4(),dt=1/2,save_everystep=false) gives BenchmarkTools.Trial:
memory estimate: 161.34 KiB
allocs estimate: 611
--------------
minimum time: 152.811 μs (0.00% GC)
median time: 167.156 μs (0.00% GC)
mean time: 197.936 μs (8.24% GC)
maximum time: 3.146 ms (92.47% GC)
--------------
samples: 10000
evals/sample: 1 So now it is faster to use Additionally, this checks out when just testing the indexing. using RecursiveArrayTools
u0 = zeros(100)
v0 = ones(100)
t1 = ArrayPartition((u0,v0))
t2 = [u0;v0]
t12 = ArrayPartition((similar(u0),similar(v0)))
t22 = similar(t2)
using BenchmarkTools
function f(t12,t1)
for i in eachindex(t12.x)
t12.x[i] .= t1.x[i] .+ t1.x[i]
end
end
@benchmark f(t12,t1)
function g(t22,t2)
t22 .= t2 .+ t2
end
@benchmark g(t22,t2)
and function h(t12,t1)
t12 .= t1 .+ t1
end
@benchmark h(t12,t1)
So once again the How about direct indexing? using BenchmarkTools
function j(t12,t1)
for i in eachindex(t12)
t12[i] .= t1[i] .+ t1[i]
end
end
@benchmark f(t12,t1)
That's much worse, so currently you should avoid ArrayPartition with #106 . Of course that cannot be fixed. But other than that, development-wise this is case closed. |
Some quick tests show that when using broadcast
ArrayPartition
s do quite well:This is great because this allows for heterogeneously typed arrays and forms the basis of the partitioned methods. But how does it do inside the full ODE solver?
This matters now because the dynamical ODEs generate a problem like this which can now be used with the general ODE solvers as a fallback, so it would be nice to reduce the overhead of that fallback, especially given that there doesn't seem to be some fundamental reason that the type's elementwise operations are slower.
That timing is with a modification to RK4 to make it use broadcast.
The text was updated successfully, but these errors were encountered: