# Creating many large arrays within structs

**URL:** <https://discourse.julialang.org/t/creating-many-large-arrays-within-structs/91160>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [December 2, 2022, 10:26pm UTC](https://discourse.julialang.org/t/creating-many-large-arrays-within-structs/91160 "2022-12-02T22:26:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![smartalecH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smartalech/32/32379_2.png) [@smartalecH](https://discourse.julialang.org/u/smartalecH)\
**Post date:** [December 2, 2022, 10:26pm UTC](https://discourse.julialang.org/t/creating-many-large-arrays-within-structs/91160/1 "2022-12-02T22:26:05Z")

</div>

Suppose I have an (immutable) struct that holds many large arrays. Not all of these arrays need to exist, however, it just depends on the user-specified problem setup. So I defined my struct like this:

```julia
@with_kw struct mystruct
    a::Union{Nothing,Matrix{Float64}} = nothing
    b::Union{Nothing,Matrix{Float64}} = nothing
    c::Union{Nothing,Matrix{Float64}} = nothing
    d::Union{Nothing,Matrix{Float64}} = nothing
end

```

Now I have some methods that initialize this struct differently depending on what the user specifies:

```julia
function init_my_struct(::Val{1})
    return mystruct(a=zeros(500,500),b=zeros(500,500))
end

function init_my_struct(::Val{2})
    return mystruct(c=zeros(500,500),d=zeros(500,500))
end

function init_my_struct(::Val{3})
    return mystruct(a=zeros(500,500),b=zeros(500,500),c=zeros(500,500),d=zeros(500,500)),
end

```

(I’m dispatching by value just to highlight the three different cases).

If you notice, the third case is really just a combination of the first two cases. In this particular example, it is easy to manually rewrite out each case. But in my actual code, I have many cases for dozens of arrays…

Is there an efficient way to pass blocks of parameters like this? Maybe via metaprogramming?

I thought about writing _another_ function (one for each case) which simply returns a vector of all the arrays for that particular case, then I could splat them as needed. However, this seems extremely inefficient as that would effectively allocate each array _twice_…

I appreciate the help!

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [December 2, 2022, 11:04pm UTC](https://discourse.julialang.org/t/creating-many-large-arrays-within-structs/91160/2 "2022-12-02T23:04:32Z")

</div>

Would named tuples work for you?

```julia
julia> ab = (a=zeros(2, 2), b=zeros(2, 2))
(a = [0.0 0.0; 0.0 0.0], b = [0.0 0.0; 0.0 0.0])

julia> cd = (c=zeros(2, 2), d=zeros(1, 1))
(c = [0.0 0.0; 0.0 0.0], d = [0.0;;])

julia> abcd = (; ab..., cd...)
(a = [0.0 0.0; 0.0 0.0], b = [0.0 0.0; 0.0 0.0], c = [0.0 0.0; 0.0 0.0], d = [0.0;;])

```

Here, the splatting allocates a new tuple, but does not allocate the arrays inside the fields

```julia
julia> ab.a[1, 2] = 1
1

julia> abcd
(a = [0.0 1.0; 0.0 0.0], b = [0.0 0.0; 0.0 0.0], c = [0.0 0.0; 0.0 0.0], d = [0.0;;])

```

and can be easily passed to your struct as well:

```julia
julia> mystruct(; ab...)
mystruct
  a: Array{Float64}((2, 2)) [0.0 1.0; 0.0 0.0]
  b: Array{Float64}((2, 2)) [0.0 0.0; 0.0 0.0]
  c: Nothing nothing
  d: Nothing nothing

```

---

<div class="post-metadata">

**Author:** ![j-fu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j-fu/32/11373_2.png) [@j-fu](https://discourse.julialang.org/u/j-fu)\
**Post date:** [December 3, 2022, 1:40pm UTC](https://discourse.julialang.org/t/creating-many-large-arrays-within-structs/91160/3 "2022-12-03T13:40:18Z")

</div>

What is the advantage of immuatbility of your struct here ? I think it is not necessary, but of course I don’t know your context.

If you can tolerate mutability, you could make your entries unions like e.g. [here](https://github.com/j-fu/ExtendableSparse.jl/blob/c02f4537e7176109fe31d68e8e43b0447e301b61/src/extendable.jl#L19), so that you can maintain type stability.

---

<div class="post-metadata">

**Author:** ![smartalecH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smartalech/32/32379_2.png) [@smartalecH](https://discourse.julialang.org/u/smartalecH)\
**Post date:** [December 5, 2022, 10:57pm UTC](https://discourse.julialang.org/t/creating-many-large-arrays-within-structs/91160/4 "2022-12-05T22:57:51Z")

</div>

> [@bertschi](#):
>
> Would named tuples work for you?

> Here, the splatting allocates a new tuple, but does not allocate the arrays inside the fields

Hey, this is clever! This works well, thank you!

---

<div class="post-metadata">

**Author:** ![smartalecH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smartalech/32/32379_2.png) [@smartalecH](https://discourse.julialang.org/u/smartalecH)\
**Post date:** [December 5, 2022, 11:00pm UTC](https://discourse.julialang.org/t/creating-many-large-arrays-within-structs/91160/5 "2022-12-05T23:00:33Z")

</div>

> What is the advantage of immuatbility of your struct here ?

These arrays are going through many loops over and over. I’m passing the struct containing all these arrays all over the place. I assumed it would help performance if I kept it immutable.

> If you can tolerate mutability, you could make your entries unions like e.g. [here](https://github.com/j-fu/ExtendableSparse.jl/blob/c02f4537e7176109fe31d68e8e43b0447e301b61/src/extendable.jl#L19), so that you can maintain type stability.

Is this not what I’m already doing above? What does mutability buy you here?

```julia
@with_kw struct mystruct
    a::Union{Nothing,Matrix{Float64}} = nothing
    b::Union{Nothing,Matrix{Float64}} = nothing
    c::Union{Nothing,Matrix{Float64}} = nothing
    d::Union{Nothing,Matrix{Float64}} = nothing
end

```
