Hi, I’m doing an MD simulation and have a problem getting good performance with static structs. The idea is to have a struct that represents a particle. I checked that using static structs is the fastest (nice) way of doing it, even if I have to override the particle when editing a field. I have the following implementation inspired by AtomsBase.jl.
using StaticArrays
struct Particle{D}
r::SVector{D, Float64}
v::SVector{D, Float64}
a::SVector{D, Float64}
m::Float64
end
This works great. But I have a lot of questions about the workflow. For example, I can make a function that edits a field, for example
function Set_r(P::Particle{D}, r::SVector{D, Float64})::Particle{D} where D
Particle(r,P.v,P.a,P.m,P.rad)
end
@btime Set_r(P, SVector(0.0,0.0,0.0))
3.370 ns (0 allocations: 0 bytes)
This works similar with all the vectors, but when I do it for the mass
function Set_m(P::Particle{D}, m::Float64)::Particle{D} where D
Particle(P.r,P.v,P.a,m,P.rad)
end
@btime Set_m(P,0.0)
20.917 ns (1 allocation: 96 bytes)
This, for me, is very weird. Why a scalar would have 1 allocation and a vector of 3 scalars won’t? Also, if I wore to add fields to the struct, suddenly the set methods will become very cumbersome to work with. Is there another way to improve this workflow?
At last, the idea is to have a vector of structs to run the simulation. Therefore I’ll be overriding the particles of the vector each time I have to update the position (for example). Is there a way to avoid allocations while doing this? What is the best way of doing this sort of thing?
@btime particles[1] = Set_r(P,SVector(0.0,0.0,0.0))
@btime particles[2] = Set_m(P,0.0)
20.628 ns (1 allocation: 96 bytes)
27.820 ns (1 allocation: 96 bytes)