# Efficiently create large array of structs without allocations

**URL:** <https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843>\
**Category:** General Usage\
**Created:** [September 28, 2021, 1:51am UTC](https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843 "2021-09-28T01:51:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [September 28, 2021, 1:51am UTC](https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843/1 "2021-09-28T01:51:58Z")

</div>

I want to create a very large array of a custom struct type. However, I am finding that the loop that fills the (pre-allocated array) is requiring a large amount of memory allocations and is very slow as a result.

I assume this is because when I set i’th array entry to MyStruct(), I am first creating MyStruct, assigning it (copying), and then immediately throwing it away. How do I avoid this?

This is a working toy code example showing the problem:

```julia
# Example code

using StaticArrays

struct MyStruct
    field1::SVector{4, Float32}
    field2::SMatrix{2, 2, Float32}
end

function myfill(arrayOfStructs)
    for i in eachindex(arrayOfStructs)
        arrayOfStructs[i] = MyStruct(
            SVector{4, Float32}([i, i, i, i]),
            SMatrix{2, 2, Float32}([i i; i i])
        )
    end
end

arrayOfStructs = Array{MyStruct}(undef, 10_000_000)

@time myfill(arrayOfStructs)

```

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 28, 2021, 1:55am UTC](https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843/2 "2021-09-28T01:55:07Z")

</div>

You want to use the macro `@SVector`. Without it, you are allocating a vanilla Julia array before converting to `SVector`. See docs [here](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/).

---

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [September 28, 2021, 3:17am UTC](https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843/3 "2021-09-28T03:17:55Z")

</div>

That’s a good catch, but I’ve oversimplified my code too much. Here’s a better example, were I’m trying to copy portions of arrays into a new array-of-structs structure.

Ideally, I would like the call to myfill() to be non-allocating, since I have already allocated space for the array. I am assuming the allocations now arise from the use of the @views?

```julia
# Example code

using BenchmarkTools
using StaticArrays

struct MyStruct
    field1::SVector{4, Float32}
    field2::SMatrix{2, 2, Float32}
end

function myfill(arrayOfStructs, origin4, origin2x2)
    for i in eachindex(arrayOfStructs)
        arrayOfStructs[i] = MyStruct(
            SVector{4, Float32}(@view origin4[i, :]),
            SMatrix{2, 2, Float32}(@view origin2x2[i, :, :])
        )
    end
end

N = 1_000_000

origin4 = rand(Float32, N, 4)
origin2x2 = rand(Float32, N, 2, 2)
arrayOfStructs = Array{MyStruct}(undef, N)

@benchmark myfill($arrayOfStructs, $origin4, $origin2x2) samples=1 evals=1 seconds=20

```

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [September 28, 2021, 7:06am UTC](https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843/4 "2021-09-28T07:06:08Z")

</div>

`MyStruct` is incompletely parameterized.

```julia
julia> struct MyStruct
           field1::SVector{4, Float32}
           field2::SMatrix{2, 2, Float32, 4} # you need to specify the length too as the fourth parameter
       end

julia> @btime myfill($arrayOfStructs, $origin4, $origin2x2);
  2.484 μs (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [September 28, 2021, 7:25am UTC](https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843/5 "2021-09-28T07:25:19Z")

</div>

Thank you! That is exactly it! 🙂

---

<div class="post-metadata">

**Author:** ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)\
**Post date:** [September 28, 2021, 7:39am UTC](https://discourse.julialang.org/t/efficiently-create-large-array-of-structs-without-allocations/68843/6 "2021-09-28T07:39:58Z")

</div>

👌 you may want to mark jishnub’s answer as “solution”.
