# Performance details of StaticArray

**URL:** https://discourse.julialang.org/t/performance-details-of-staticarray/11506
**Category:** Performance
**Created:** [June 7, 2018, 2:33pm UTC](https://discourse.julialang.org/t/performance-details-of-staticarray/11506 "2018-06-07T14:33:28Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Gyslain](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gyslain/32/4411_2.png) [@Gyslain](https://discourse.julialang.org/u/Gyslain)
#### Post date: [June 7, 2018, 2:33pm UTC](https://discourse.julialang.org/t/performance-details-of-staticarray/11506/1 "2018-06-07T14:33:28Z")

</div>

Hello!  
In the [StaticArray](https://github.com/JuliaArrays/StaticArrays.jl) documentation, we read :

1. The speed of small SVectors, SMatrixs and SArrays is often \> 10 × faster than Base.Array
2. These results improve significantly when using julia -O3 with immutable static arrays, as the extra optimization results in surprisingly good SIMD code.
3. A very rough rule of thumb is that you should consider using a normal Array for arrays larger than 100 elements.

Could you please explain a bit more the reasons of the performance gain of 1. and loss of 3. ?  
One reason I see is statically sized array can improve loop unrolling.  
Anything else?

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [June 7, 2018, 9:06pm UTC](https://discourse.julialang.org/t/performance-details-of-staticarray/11506/2 "2018-06-07T21:06:29Z")

</div>

Well, I think using StaticArrays avoids calling OpenBlas. OpenBlas has a curtain call overhead, which is worth using it for larger arrays, but not for smaller arrays. In addition SArrays are stack allocated and not heap allocated. Not sure about mutable MVectos, though.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [June 7, 2018, 9:18pm UTC](https://discourse.julialang.org/t/performance-details-of-staticarray/11506/3 "2018-06-07T21:18:10Z")

</div>

> [@ufechner7](#):
>
> In addition SArrays are stack allocated and not heap allocated. Not sure about mutable MVectos, though.

SArrays are structs of tuples. MArrays are tuples in a mutable struct. StaticArrays.jl then writes `@generated` functions which generate the hand-done code based on the size of the array, so yes it completely avoids BLAS and in many cases avoids any and all looping and just evaluates straight statements. For example, matrix multiplication can be tough to read:

> <https://github.com/JuliaArrays/StaticArrays.jl/blob/master/src/matrix_multiply.jl>

but the matrix inverses are hard coded for the small case and you can see why this would be much faster than a generic algorithm:

> <https://github.com/JuliaArrays/StaticArrays.jl/blob/master/src/inv.jl>

Then they all SIMD really well as well.

So there’s two things going on. SArrays are stack-allocated, so there’s no heap allocations when using them. Then they have fast dispatches based on their size. So if you’re small enough to where Julia tuples are fast, these are fast.

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [June 7, 2018, 10:10pm UTC](https://discourse.julialang.org/t/performance-details-of-staticarray/11506/4 "2018-06-07T22:10:51Z")

</div>

Re loss for large SVectors:

```julia
julia> using StaticArrays
julia> v=SVector(collect(1:1000)...);
julia> @time +(v,v);
  2.412768 seconds (846.77 k allocations: 43.634 MiB, 6.45% gc time)
julia> @code_native +(v,v);
 [disgusting no-jump code]

```

Branches are not _that_ expensive, and fully unrolling the loop is very bad, both for compile speeds and runtime speeds (instruction cache is limited).

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [June 7, 2018, 10:25pm UTC](https://discourse.julialang.org/t/performance-details-of-staticarray/11506/5 "2018-06-07T22:25:19Z")

</div>

Do they _have_ to avoid branches for some reason, or is that a conscious tradeoff?

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [June 7, 2018, 11:04pm UTC](https://discourse.julialang.org/t/performance-details-of-staticarray/11506/6 "2018-06-07T23:04:39Z")

</div>

I know you know, but just so that it’s clear to everybody else: that’s mostly measuring compilation time.

StaticArrays falls back to a chunked approach or to BLAS for some operations after a certain size limit, but this is not one of those operations. In general, I wouldn’t rely on StaticArrays making the right decision as to when it is beneficial to fall back to BLAS, also because the cutoff point is kind of subjective (how much compilation time is too much, for example?).

> [@cstjean](#):
>
> Do they _have_ to avoid branches for some reason, or is that a conscious tradeoff?

Conscious decision that works well for small arrays.
