# What is meant by this tip for StaticArrays?

**URL:** <https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757>\
**Category:** Performance\
**Created:** [February 5, 2024, 6:48pm UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757 "2024-02-05T18:48:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [February 5, 2024, 6:48pm UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757/1 "2024-02-05T18:48:04Z")

</div>

Hello!

In the Github of StaticArrays.jl, the following is stated:

> Note that in the current implementation, working with large `StaticArray` s puts a lot of stress on the compiler, and becomes slower than `Base.Array` as the size increases. A very rough rule of thumb is that you should consider using a normal `Array` for arrays larger than 100 elements.

What is **exactly** meant here?

Is it in pseudo code;

1. A `SVector{100,Float64}` should be avoided
2. A `Vector{SVector,N}` where N = 100+ should be avoided?

I have not been able to find a time where I would ever do the first option, so I take it as option 2 being what is meant?

And in regards to “stress on the compiler”, is what is meant here that the garbage collection mechanism in Julia gets stressed or?

Kind regards

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 5, 2024, 6:55pm UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757/2 "2024-02-05T18:55:42Z")

</div>

Imagine summing an array of 100 elements, you can do this with the loop `for i = 1:100`, or you can do this using `x[1] + x[2] + x[3] + ...`.  
Using standard arrays, many algorithms are implemented as loops, and those do not grow in compilation complexity with the number of elements in the array. StaticArrays often makes use of completely _unrolled_ code, i.e., something closer to `x[1] + x[2] + x[3] + ...`. The expression grows in compilation complexity with the length of the array, and for large arrays this ends up taking a long time to compile, and the code ends up being slower than the loop version. The compiled version of the loop is only a small number of assembly instructions, while the unrolled compiled code has a ton of instructions. All of those instructions might not fit into the instruction cache of the processor, making the code slow.

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [February 5, 2024, 7:24pm UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757/3 "2024-02-05T19:24:37Z")

</div>

(Edited to explicitly state that the element type must be concrete for good performance, as pointed out by @DNF below)

To answer your question directly, it is your item 1. that should be avoided (or at least not exceeded). Large arrays with an element type of some concrete `SVector` are very performant and are a common idiom in Julia for representing, say, spatial coordinates.

---

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [February 5, 2024, 7:46pm UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757/4 "2024-02-05T19:46:43Z")

</div>

@baggepinnen thank you for the detailed explanation. You made concepts such as unrolling clear to me and what it actually means now, thanks!

@PeterSimon thank you for confirming for me that I understood the above answer correctly, that it is item 1 and not item 2 as I initially thought.

I have experienced that using `Vector{SVector}` leads to some weird garbage collection behaviour / allocations while using 1D vectors to represent spatial coordinates, x, y and z does not. This is what pushed me to make this question to begin with. Is it correctly understood by me that there is no `magic` in StaticArrays, so if I do everything with for loops manually, then I should still see great performance?

Kind regards

---

<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:** [February 5, 2024, 7:53pm UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757/5 "2024-02-05T19:53:51Z")

</div>

You can get a lot of added benefit from using vectors of SVectors, that is a common use case for improved performance. If you are having strange performance issues, maybe you can share some of your code?

In particular, note that `Vector{SVector}` will be slow, since this is an abstract `eltype`, while eg. `Vector{SVector{3, Float64}}` should be efficient.

---

<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:** [February 5, 2024, 7:58pm UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757/6 "2024-02-05T19:58:56Z")

</div>

> Is it correctly understood by me that there is no `magic` in StaticArrays, so if I do everything with for loops manually, then I should still see great performance?

This is correct. The reason `SVector` is fast are because

1. the compiler knows the length
2. the memory layout is optimal (e.g. `Vector{SVector{3, Float64}}` is just a single chunk of memory.

---

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [February 6, 2024, 8:21am UTC](https://discourse.julialang.org/t/what-is-meant-by-this-tip-for-staticarrays/109757/7 "2024-02-06T08:21:49Z")

</div>

Basically this thread here covers an example of the issue. It seems to only pop up when running multiple iterations of a simulation, i.e. using `BenchmarkTools` all allocations are zero etc.

> [@Profiling in VSCode returns some red bars with "Flag: GC" - what do they mean?](https://discourse.julialang.org/t/profiling-in-vscode-returns-some-red-bars-with-flag-gc-what-do-they-mean/109570/5):
>
> You commented the perfect time, was just testing something. Basically using TimerOutputs package I am tracking each function - I think there is a bug in the package somewhere, since I see a low number of allocs for functions when BenchmarkTools would say zero. But back on track the function updatexᵢⱼ! returns 0 allocs: But I get the GC flag for this function and two others as well; And I just don’t know why. Kind regards

When I went away from using StaticArrays and only used 1D vectors, this issue with GC for `updatexᵢⱼ!` (in the link) would be gone - but not when using StaticArrays. So I am suspecting some issue with StaticArrays here - perhaps from my use.

Kind regards
