Let’s make things a little bit more interesting by throwing in regular arrays
and increasing the size of the data structure.
using StaticArrays
struct Point3D{T} <: FieldVector{3, T}
x::T
y::T
z::T
end
mutable struct MPoint3D{T} <: FieldVector{3, T}
x::T
y::T
z::T
end
function f1!(v)
for i in eachindex(v)
x, y, z = v[i]
v[i] = Point3D(2x, x*y, x*z)
end
end
function f2!(v)
for i in eachindex(v)
x, y, z = v[i]
v[i] .= (2x, x*y, x*z)
end
end
function f5!(v)
for i in 1:size(v, 1)
x, y, z = v[i, 1], v[i, 2], v[i, 3]
v[i, 1], v[i, 2], v[i, 3] = 2x, x*y, x*z
end
end
function f6!(v)
for i in 1:size(v, 2)
x, y, z = v[1, i], v[2, i], v[3, i]
v[1, i], v[2, i], v[3, i] = 2x, x*y, x*z
end
end
using BenchmarkTools
v1 = [@SVector(rand(3)) for i = 1:1000000]
v2 = [@MVector(rand(3)) for i = 1:1000000]
v3 = [Point3D(rand(3)) for i = 1:1000000]
v4 = [MPoint3D(rand(3)) for i = 1:1000000]
v5 = rand(1000000, 3)
v6 = rand(3, 1000000)
@btime f1!($v1) # 1.693 ms (0 allocations: 0 bytes)
@btime f2!($v2) # 2.821 ms (0 allocations: 0 bytes)
@btime f1!($v3) # 1.728 ms (0 allocations: 0 bytes)
@btime f2!($v4) # 57.962 ms (3000000 allocations: 45.78 MiB)
@btime f5!($v5) # 1.518 ms (0 allocations: 0 bytes)
@btime f6!($v6) # 1.739 ms (0 allocations: 0 bytes)