# How to initialize an empty StaticArray?

**URL:** <https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942>\
**Category:** General Usage\
**Created:** [October 17, 2021, 7:40pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942 "2021-10-17T19:40:16Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![curious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/curious/32/7629_2.png) [@curious](https://discourse.julialang.org/u/curious)\
**Post date:** [October 17, 2021, 7:40pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/1 "2021-10-17T19:40:16Z")

</div>

For performance reasons, I want to replace usage of standard arrays with StaticArrays. However, I couldn’t find how to initialize an empty StaticArray of a given size, that I can populate as values become available. I am looking for something equivalent of:

```julia
Array{Int64}(undef, 10)

```

but for StaticArrays. Is this possible?

Thank you.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 17, 2021, 7:51pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/2 "2021-10-17T19:51:16Z")

</div>

Theoretically yes, as I learned from [Create a struct with uninitialized fields](https://discourse.julialang.org/t/create-a-struct-with-uninitialized-fields/6967). But practically: I don’t know.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 17, 2021, 7:54pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/3 "2021-10-17T19:54:57Z")

</div>

since staticarray is static, if you created an empty one, you couldn’t ever put stuff in it.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 17, 2021, 7:58pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/4 "2021-10-17T19:58:20Z")

</div>

I see. But you still could replace it in nested container;)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 17, 2021, 8:00pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/5 "2021-10-17T20:00:54Z")

</div>

Static arrays are like numbers. You cannot create an empty number, and if you have a vector of numbers, when you want to change a value you _replace_ the number at a position in the vector by another number.

The same goes for static arrays. They are not mutable, you have to create them with values and replace them when needed. This is advantageous when the arrays are small.

---

<div class="post-metadata">

**Author:** ![curious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/curious/32/7629_2.png) [@curious](https://discourse.julialang.org/u/curious)\
**Post date:** [October 17, 2021, 8:07pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/6 "2021-10-17T20:07:25Z")

</div>

Thank you for the explanation. I misunderstood them. I thought that there size could not be changed, however, the values in them could be changed. For example, the following code works, and does not throw any errors.

```julia
function arr3(len)
	a = Array{Int}(undef, len)
	a = StaticArrays.SizedVector{len}(a)
	for i = 1:len
		a[i] = i
	end
	for j = 1:1000
		a[rand(1:len)]
	end
end

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 17, 2021, 8:14pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/7 "2021-10-17T20:14:48Z")

</div>

Oh yes, StaticArrays also provides mutable, statically sized arrays. For those the explanation above does not apply. (But the performance is not the same either).

The interface for mutable, statically sized, arrays in StaticArrays is the MArray. (I never saw the use of that constructor you used there before, I guess it is an internal).

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 17, 2021, 8:18pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/8 "2021-10-17T20:18:06Z")

</div>

That’s the kind of example I love: using a dynamic array to initialize a possibly static array;)

---

<div class="post-metadata">

**Author:** ![curious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/curious/32/7629_2.png) [@curious](https://discourse.julialang.org/u/curious)\
**Post date:** [October 17, 2021, 8:19pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/9 "2021-10-17T20:19:10Z")

</div>

Thank you! For these statically sized arrays, is the performance better than the regular arrays? And, if yes, can these by initialized with `undef` or something similar?

The constructor I used is documented here:  
[https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.SizedArray](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.SizedArray)

Thanks again.

---

<div class="post-metadata">

**Author:** ![curious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/curious/32/7629_2.png) [@curious](https://discourse.julialang.org/u/curious)\
**Post date:** [October 17, 2021, 8:22pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/10 "2021-10-17T20:22:20Z")

</div>

I am not suggesting that that is a good way 🙂

But I did try to see if that helped over just using the dynamic array, and it did not. It made performance much worse. Hence, my question.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [October 17, 2021, 9:37pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/11 "2021-10-17T21:37:37Z")

</div>

```julia
julia> using StaticArrays

julia> MVector{10,Float64}(undef)
10-element MVector{10, Float64} with indices SOneTo(10):
 4.4e-323
 6.9288606158516e-310
 6.92886061148325e-310
 0.0
 6.9288606158516e-310
 6.92886061148325e-310
 0.0
 6.9288606158516e-310
 6.9288723779309e-310
 0.0

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 17, 2021, 9:40pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/12 "2021-10-17T21:40:54Z")

</div>

Maybe this can help you understand where these static arrays can be useful: [Immutable variables · JuliaNotes.jl](https://m3g.github.io/JuliaNotes.jl/stable/immutable/)

---

<div class="post-metadata">

**Author:** ![curious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/curious/32/7629_2.png) [@curious](https://discourse.julialang.org/u/curious)\
**Post date:** [October 17, 2021, 9:46pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/13 "2021-10-17T21:46:26Z")

</div>

Thank you, Elrod for the solution.

Thank you also [leandromartinez98] for the link. I will read it. On my computer, the `MVector` works slower than a regular `Array`. I have included a small example I tried. But the link you have will probably shed light on that.

```julia
function arr2(len)
	a = Array{Int}(undef, len)
	for i = 1:len
		a[i] = i
	end
	for j = 1:1000
		a[rand(1:len)]
	end
end

function arr3(len)
	a = MVector{len, Int}(undef)
	for i = 1:len
		a[i] = i
	end
	for j = 1:1000
		a[rand(1:len)]
	end
end

```

```julia
julia> @btime arr2(100)
  6.408 μs (1 allocation: 896 bytes)

julia> @btime arr3(100)
  20.429 μs (10 allocations: 1.36 KiB)

```

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [October 17, 2021, 10:19pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/14 "2021-10-17T22:19:15Z")

</div>

The length of a static array is part of its type. Thus, passing `len` as an `Int` results in dynamic dispatches: the only thing known at compile time is that `len` is an `Int`.  
If you instead pass it as a `::Val{len}`, that is an object of type `Val{len}`, then the value is known at compile time.

```julia
julia> function arr3(::Val{len}) where {len}
           a = MVector{len, Int}(undef)
           for i = 1:len
               @inbounds a[i] = i
           end
           for j = 1:1000
               @inbounds a[rand(1:len)]
           end
       end
arr3 (generic function with 2 methods)

julia> @btime arr2(100)
  3.553 μs (1 allocation: 896 bytes)

julia> @btime arr3(100)
  18.291 μs (10 allocations: 1.30 KiB)

julia> @btime arr3(Val(100))
  3.129 μs (0 allocations: 0 bytes)

```

Note also the 0 allocations.  
If you want to actually return `a` from the function, call `SVector(a)` to convert it into an `SVector` before returning to still get 0 allocations.

---

<div class="post-metadata">

**Author:** ![curious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/curious/32/7629_2.png) [@curious](https://discourse.julialang.org/u/curious)\
**Post date:** [October 17, 2021, 10:30pm UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/15 "2021-10-17T22:30:26Z")

</div>

Thanks very much for the explanation. I did not know anything about `Val`. Will read up on that.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 18, 2021, 1:09am UTC](https://discourse.julialang.org/t/how-to-initialize-an-empty-staticarray/69942/16 "2021-10-18T01:09:50Z")

</div>

Although the suggestion above is of course valid, I think it is not a common pattern (please Elrod correct me if I’m wrong), because:

1. That function specializes for every `len`. Thus, if the lengths of your arrays are changing frequently in your code, that will cause dynamic dispatch to kick in (every time you call the function with a different len it will call a different method of the function). In these cases using static arrays may not be worthwhile anyway.

2. Most commonly the length of the array you want to create can be deduced from some of the input parameters of your function. For example, this is more common:

```julia
julia> f(x::T) where T = x + rand(T)
f (generic function with 1 method)

julia> x = SVector{3,Float64}(1,1,1)
3-element SVector{3, Float64} with indices SOneTo(3):
 1.0
 1.0
 1.0

julia> @btime f($x)
  10.620 ns (0 allocations: 0 bytes)
3-element SVector{3, Float64} with indices SOneTo(3):
 1.9554100262060785
 1.1736294084146963
 1.5112265205467528

```

You don’t need to specify explicitly the size of the random vector that is being created inside, because you know that it has to be of the same size as `x`. And if `x` is a static array, the random vector will have the same type.

As you see, in the example above there is no “uninitialized” array, the `rand(T)` creates the random vector, which is added to `x`. There are may ways (which do not solve _all_ problems, but many of them), to build these arrays, for example, using ntuples:

```julia
julia> g(x::SVector{N,T}) where {N,T} = x + SVector{N,T}(ntuple(i -> 2*i, N))
g (generic function with 1 method)

julia> x = SVector{3,Int}(1,1,1)
3-element SVector{3, Int64} with indices SOneTo(3):
 1
 1
 1

julia> @btime g($x)
  0.022 ns (0 allocations: 0 bytes)
3-element SVector{3, Int64} with indices SOneTo(3):
 3
 5
 7

```

Here `x` is being added to a static vector of the same type, but which is constructed from a n-tuple. Since `N` is the length of the ntuple and is a parameter of the type of `x`, it is known at compile time as well, and the function specializes to it.

With the `do` syntax you can build pretty complicated arrays with that:

```julia
julia> function h(x::SVector{N,T}) where {N,T}
           y = ntuple(N) do i
                   if i == 1 
                       zero(T)
                   else
                       10*i*rand(T)
                   end
               end
           return x + SVector{N,T}(y)
       end
h (generic function with 1 method)

julia> x = zeros(SVector{5,Float64});

julia> @btime h($x)
  21.608 ns (0 allocations: 0 bytes)
5-element SVector{5, Float64} with indices SOneTo(5):
  0.0
  2.4393119543628927
  8.108974913748623
 37.62484099830813
 13.538314396037276

```
