# Performance assigning and copying with StaticArrays.jl

**URL:** <https://discourse.julialang.org/t/performance-assigning-and-copying-with-staticarrays-jl/74182>\
**Category:** New to Julia\
**Tags:** performance, memory-allocation, staticarrays\
**Created:** [January 7, 2022, 10:37am UTC](https://discourse.julialang.org/t/performance-assigning-and-copying-with-staticarrays-jl/74182 "2022-01-07T10:37:37Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![drandran12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drandran12/32/220647_2.png) [@drandran12](https://discourse.julialang.org/u/drandran12)\
**Post date:** [January 7, 2022, 10:37am UTC](https://discourse.julialang.org/t/performance-assigning-and-copying-with-staticarrays-jl/74182/1 "2022-01-07T10:37:37Z")

</div>

I was thinking of using the package StaticArrays.jl to enhance the performance of my code. However, I only use arrays to store computed variables and use them later after certain conditions are set. Hence, I was benchmarking the type SizedVector in comparison with normal vector, but I do not understand to code below. I also tried StaticVector and used the work around Setfield.jl.

```julia
using StaticArrays, BenchmarkTools, Setfield
function copySized(n::Int64)
    v = SizedVector{n, Int64}(zeros(n))
    w = Vector{Int64}(undef, n)
    for i in eachindex(v)
        v[i] = i
    end
    for i in eachindex(v)
        w[i] = v[i]
    end
end
function copyStatic(n::Int64)
    v = @SVector zeros(n)
    w = Vector{Int64}(undef, n)
    for i in eachindex(v)
        @set v[i] = i
    end
    for i in eachindex(v)
        w[i] = v[i]
    end
end
function copynormal(n::Int64)
    v = zeros(n)
    w = Vector{Int64}(undef, n)
    for i in eachindex(v)
        v[i] = i
    end
    for i in eachindex(v)
        w[i] = v[i]
    end
end
n = 10
@btime copySized($n)
@btime copyStatic($n)
@btime copynormal($n)

3.950 μs (42 allocations: 2.08 KiB)
5.417 μs (98 allocations: 4.64 KiB) 
78.822 ns (2 allocations: 288 bytes)

```

Why does the case with SizedVector does have some much more allocations and hence worse performance? Do I not use SizedVector correctly? Should it not at least have the same performance as normal arrays?

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [January 7, 2022, 12:30pm UTC](https://discourse.julialang.org/t/performance-assigning-and-copying-with-staticarrays-jl/74182/2 "2022-01-07T12:30:20Z")

</div>

Just a guess, but the loop contents are simple enough that the compiler is probably optimizing the loop away in the latter case. The `Vector` version is benefitting from that, but the non-builtin types can’t.

As soon as the loop has some non-trivial code that the compiler can’t just optimize away, the `Vector` version will start actually looping and then allow you measure the actual performance difference.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 7, 2022, 1:06pm UTC](https://discourse.julialang.org/t/performance-assigning-and-copying-with-staticarrays-jl/74182/3 "2022-01-07T13:06:45Z")

</div>

Statically sized arrays have their performance advantages when the size is known statically, at compile time. Your arrays are, however, _dynamically_ sized, with the size `n` being a runtime variable.

---

<div class="post-metadata">

**Author:** ![drandran12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drandran12/32/220647_2.png) [@drandran12](https://discourse.julialang.org/u/drandran12)\
**Post date:** [January 7, 2022, 1:12pm UTC](https://discourse.julialang.org/t/performance-assigning-and-copying-with-staticarrays-jl/74182/4 "2022-01-07T13:12:38Z")

</div>

You are right! I overlooked this. Thanks!

```julia
using StaticArrays, BenchmarkTools, Setfield
function copySized()
    v = SizedVector{10, Float64}(zeros(10))
    w = Vector{Float64}(undef, 10*2)
    for i in eachindex(v)
        v[i] = rand()
    end
    for i in eachindex(v)
        j = i+floor(Int64, 10/4)
        w[j] = v[i]
    end
end
function copyStatic()
    v = @SVector zeros(10)
    w = Vector{Int64}(undef, 10*2)
    for i in eachindex(v)
       @set v[i] = rand()
    end
    for i in eachindex(v)
        j = i+floor(Int64, 10/4)
        w[j] = v[i]
    end
end
function copynormal()
    v = zeros(10)
    w = Vector{Float64}(undef, 10*2)
    for i in eachindex(v)
        v[i] = rand()
    end
    for i in eachindex(v)
        j = i+floor(Int64, 10/4)
        w[j] = v[i]
    end
end
@btime copySized()
@btime copyStatic()
@btime copynormal()

 110.162 ns (3 allocations: 512 bytes)
 48.133 ns (1 allocation: 224 bytes)
 92.045 ns (2 allocations: 368 bytes)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 7, 2022, 1:12pm UTC](https://discourse.julialang.org/t/performance-assigning-and-copying-with-staticarrays-jl/74182/5 "2022-01-07T13:12:54Z")

</div>

Here’s a version that is statically sized:

```julia
function copyStaticStatic(::Val{N}) where {N}
    v = @SVector zeros(N)
    w = Vector{Int64}(undef, N)
    for i in eachindex(v)
        @set v[i] = i
    end
    for i in eachindex(v)
        w[i] = v[i]
    end
end

1.7.0> @btime copyStaticStatic(Val(10))
  27.108 ns (1 allocation: 144 bytes)

```

**Edit:** Ah, too late 🙂
