Meanwhile, in Julia 1.4 there are already 4 allocations in the above code.
Just to highlight the problem, the following code
using BenchmarkTools
# import DifferentialEquations
function foo(u, k1, k2, k3, k4)
for i=1:1000
@. u = u + 1.0 * (k1 + k2 + k3 + k4)
end
return nothing
end
function main()
u = rand(100)
k1 = zero(u)
k2 = zero(u)
k3 = zero(u)
k4 = zero(u)
@btime foo($u, $k1, $k2, $k3, $k4)
end
main()
results in
155.048 μs (4000 allocations: 93.75 KiB)
Surprisingly, if I import DifferentialEquations (uncomment the second line), the result will be
122.759 μs (0 allocations: 0 bytes)
That is, there are no more allocations.
The above code is typical for various Runge-Kutta methods. So far in my realizations of Runge-Kutta methods of order higher than 3 I inevitably see these broadcasting allocations. Can you, please, help me to understand what is going on. Especially, why the import of DifferentialEquations solves the problem.
There wasn’t before, but https://github.com/JuliaLang/julia/pull/35260 is it. Someone should probably double check that those changes are sufficient to get rid of these allocations.
Splatting can sometimes cause a tuple to allocate if everything doesn’t inline or the world doesn’t align its chakras correctly. This makes it so that way a common case doesn’t ever splat, so boom now it can’t be a problem.
I find it’s easiest to just do @eval Base.Broadcast begin ... end to paste in these sorts of patches interactively without editing. You can also use Revise, but that can be trickier and isn’t as obvious.