# Runtime creation of SArray

**URL:** https://discourse.julialang.org/t/runtime-creation-of-sarray/62377
**Category:** New to Julia
**Created:** [June 4, 2021, 6:40am UTC](https://discourse.julialang.org/t/runtime-creation-of-sarray/62377 "2021-06-04T06:40:54Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![mapclyps](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mapclyps/32/6309_2.png) [@mapclyps](https://discourse.julialang.org/u/mapclyps)
#### Post date: [June 4, 2021, 6:40am UTC](https://discourse.julialang.org/t/runtime-creation-of-sarray/62377/1 "2021-06-04T06:40:54Z")

</div>

I have a program where small arrays are involved where the size need to change at some point at runtime depending on some computations. Nevertheless, I wanted to use StaticArrays since there is some linear algebra involved in the end which way faster with SArrays in that size.

Since the length is a required parameter for SArrays I came across `Val` types to reduce the cost of runtime creation of the SArrays

```julia
using StaticArrays
using BenchmarkTools

function make_SVector_1(a) 
    return SVector{length(a)}(a)
end

function make_fixed_length_SV(a,::Val{N}) where N
    return SVector{N}(a)
end

function make_SVector_2(a) #just a convenience wrapper
    return make_fixed_length_SV(a,Val{length(a)}())
end

a=rand(20)

@btime make_SVector_1(a)
 1.059 μs (10 allocations: 752 bytes)
 
@btime make_SVector_2(a)
 165.854 ns (1 allocation: 176 bytes)

```

So timewise the second variant I can tolerate in the code.  
Is there any reason to not do this or is there a better way to create an SArray at runtime?

---

<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: [June 4, 2021, 3:46pm UTC](https://discourse.julialang.org/t/runtime-creation-of-sarray/62377/2 "2021-06-04T15:46:39Z")

</div>

Probably you should stick to the default constructors available, `@SVector(a)`. But the most important for performance is to keep function barriers that preserve type stability of the foregoing computations after that size change.

```julia
julia> f(a) = @SVector [a[i] for i in 1:length(a)]
f (generic function with 1 method)

julia> @btime f($a)
  8.286 ns (0 allocations: 0 bytes)

```

**edit:** In the example above I have been fooled by the fact that `a` is defined when the macro `@SVector` is parsed, thus the length of it is known at compile time. You cannot do that dynamically with the same performance.

If you know exactly the initial and final sizes and values, you can try something more sophisticated, like this:

```julia
julia> a = rand(SVector{3,Float64})

julia> f(a::SVector{N,T},x) where {N,T} = SVector{N+1,T}(ntuple(i -> i <= N ? a[i] : x, N+1))
f (generic function with 2 methods)

julia> f(a,1.0)
4-element SVector{4, Float64} with indices SOneTo(4):
 0.08759991208199902
 0.38144466002582855
 0.658066648655117
 1.0

julia> @btime f(x,1.0) setup=(x=rand(SVector{3,Float64})) evals=1
  23.000 ns (0 allocations: 0 bytes)
4-element SVector{4, Float64} with indices SOneTo(4):
 0.6213191707449999
 0.1885468618825823
 0.07677713807317965
 1.0

```

---

<div class="post-metadata">

### Author: ![mapclyps](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mapclyps/32/6309_2.png) [@mapclyps](https://discourse.julialang.org/u/mapclyps)
#### Post date: [June 4, 2021, 5:09pm UTC](https://discourse.julialang.org/t/runtime-creation-of-sarray/62377/3 "2021-06-04T17:09:37Z")

</div>

The constructor was exactly my issue. So when the size is known at compile time that works well, but fastest runtime creation I could only get via this workaround which is to my understanding basically like you suggested a function barrier.  
So currently I have just these little helper functions from my first post in my code for creating SVectors from any Vector on the fly. But maybe just have this as a constructor of an SVector like `SVector(a)` would be nice.  
For sure it would be better to not have to do runtime creation of any `SArray` at all.

regarding extending a `SVector`, that works already pretty nice like

```julia
@btime [c;1] setup=c=SVector{3}(1.0,2.0,3.0) evals=1
20.000 ns (0 allocations: 0 bytes)
4-element SVector{4, Float64} with indices SOneTo(4):
 1.0
 2.0
 3.0
 1.0

```

which is probably implemented similar to what you suggested, but I haven’t checked.  
I did not know about the `evals` argument from `@btime` but it helps a lot with the timing of SArray things. Thanks 🙂
