# Best practice to use lots of pre-allocated arrays in a function

**URL:** <https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353>\
**Category:** General Usage\
**Tags:** arrays, input-output, function\
**Created:** [March 3, 2022, 1:18pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353 "2022-03-03T13:18:01Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Iddingsite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iddingsite/32/31840_2.png) [@Iddingsite](https://discourse.julialang.org/u/Iddingsite)\
**Post date:** [March 3, 2022, 1:18pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/1 "2022-03-03T13:18:02Z")

</div>

I am still quite new to Julia, working on numerical modeling and I am starting to write a bigger project than usual.

I have a function that takes, as arguments, lots of pre-allocated arrays and parameters and update them in different ways using different functions. I am wondering what would be the best practice to store them and update them?

In pseudocode:

```julia
array1 = zeros(nx)
array2 = zeros(nx)
array3 = zeros(nx)
...

function update!(array1, array2, array3,...., parameters)
    updatearray1!(array1, parameters..)
    updatearray2!(array2, parameters..)
    updatearray3!(array3, parameters..)
end

```

What bother me here is that I have lots of arguments for my function. I was wondering what is the common practice for storing pre-allocated arrays?

My idea would be to store them all in an array, input that in the function, and use @view at the beginning of the function for each separate array, and inputing that in the internal functions. Is there a better way to do that?

I have started to work with Parameters.jl for storing the constant of my models and it is working great. So I am looking for something similar to Parameters.jl where I can easily update the arrays with their new values.

Tell me if it is confusing. I am just looking for the best practices for dealing with lots of preallocated arrays.

Thanks.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 3, 2022, 2:18pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/2 "2022-03-03T14:18:36Z")

</div>

Personally, I like creating a “workspace” struct to hold this kind of data. Something like:

```julia
struct Myworkspace
  x::Vector{Float64}
  y::Vector{Float64}
end

function update!(workspace::MyWorkspace, parameters)
  # do stuff with `workspace.x` etc.
end

```

Then you can also write a convenience function if you want:

```julia
function update(parameters)
  work = MyWorkspace(...)
  update!(work, parameters)
end

```

which is less efficient but very convenient for testing or interactive usage.

---

<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:** [March 3, 2022, 2:26pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/3 "2022-03-03T14:26:31Z")

</div>

> [@Iddingsite](#):
>
> So I am looking for something similar to Parameters.jl where I can easily update the arrays with their new values.

Note that the arrays within a struct are still mutable, so you can use that package for organizing your arrays. Or a named tuple:

```julia
julia> myarrays = ( arr1 = [1,2], arr2 = [3,4] )
(arr1 = [1, 2], arr2 = [3, 4])

julia> function f(myarrays)
           myarrays.arr1[1] = 0
       end
f (generic function with 1 method)

julia> f(myarrays)
0

julia> myarrays
(arr1 = [0, 2], arr2 = [3, 4])

```

---

<div class="post-metadata">

**Author:** ![Iddingsite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iddingsite/32/31840_2.png) [@Iddingsite](https://discourse.julialang.org/u/Iddingsite)\
**Post date:** [March 3, 2022, 2:26pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/4 "2022-03-03T14:26:48Z")

</div>

Thx, that’s what I was looking for! I am still quite new to structure, but I am already liking it.

---

<div class="post-metadata">

**Author:** ![Iddingsite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iddingsite/32/31840_2.png) [@Iddingsite](https://discourse.julialang.org/u/Iddingsite)\
**Post date:** [March 3, 2022, 2:31pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/5 "2022-03-03T14:31:21Z")

</div>

Sorry, I replied at the same time. Thx for the tips, that’s actually quite neat!

EDIT

I tried to do what you did with struct, and arrays don’t seem to be updated in that case, at least when I am doing it that way:

```julia
julia> using Parameters

julia> @with_kw struct test
           u0::Vector{Float64} = zeros(5)
       end
test

julia> function f(test)
           @unpack u0 = test()
           u0 .= 2
       end
f (generic function with 1 method)

julia> f(test)
5-element Vector{Float64}:
 2.0
 2.0
 2.0
 2.0
 2.0

julia> test().u0
5-element Vector{Float64}:
 0.0
 0.0
 0.0
 0.0
 0.0

```

Did I miss something?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [March 3, 2022, 4:17pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/6 "2022-03-03T16:17:42Z")

</div>

This defines a new type with the name `test`. By default, its constructor creates an instance which holds a freshly-allocated vector

```julia
julia> @with_kw struct test
           u0::Vector{Float64} = zeros(5)
       end

```

This defines a function that accepts a callable and binds it to the name `test` within its body

```julia
julia> function f(test)
           @unpack u0 = test() # calls the `test` that is passed as argument
           u0 .= 2
       end

```

The defined function is called on a type constructor:

```julia
julia> f(test)

```

`u0` within `f` is a freshly created array.

`test()` allocates a fresh array:

```julia
julia> test().u0

```

If you come from Python, you may have the impression that a mutable default argument for a function or a default mutable attribute for a class is created on function/class definition. In Julia, the default argument is _an expression_ which is evaluated each time the function or constructor is called.

What @rdeits and @lmiq advised can be done as:

```julia
julia> @with_kw struct TestStruct
           u0::Vector{Float64} = zeros(5)
       end
test

julia> function f(test)
           @unpack u0 = test
           u0 .= 2
       end

julia> test_obj = TestStruct();

julia> f(test_obj)

julia> test_obj.u0

```

---

<div class="post-metadata">

**Author:** ![Iddingsite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iddingsite/32/31840_2.png) [@Iddingsite](https://discourse.julialang.org/u/Iddingsite)\
**Post date:** [March 3, 2022, 4:47pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/7 "2022-03-03T16:47:27Z")

</div>

Great, it is pretty clear for me now. Thx for deconstructing my code, it helps. It also explains why I had 1 allocation on my f function before.

So my mistake was to use TestStruct() as an argument. Even though I can define default values using Parameters.jl, TestStruct() is still a Type constructor, and I should then build an object from it.

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [March 4, 2022, 12:32pm UTC](https://discourse.julialang.org/t/best-practice-to-use-lots-of-pre-allocated-arrays-in-a-function/77353/8 "2022-03-04T12:32:10Z")

</div>

As of Julia 1.8.0, working with typed globals is perfectly fine. Despite the disadvantages of using global variables, the introduction of this nice feature can help reduce much of the noise caused by passing the same variables to multiple functions. The following function `update!(..)` causes 0-allocations:

```julia
nx::Int64 = 10
array1::Vector{Float64} = ones(nx)
array2::Vector{Float64} = ones(nx)
array3::Vector{Float64} = ones(nx)

updatearray1!(array,parameters) = array .+= sum(parameters)
updatearray2!(array,parameters) = array .+= minimum(parameters)
updatearray3!(array,parameters) = array .+= maximum(parameters)

function update!(parameters)
   updatearray1!( array1, parameters )
   updatearray2!( array2, parameters )
   updatearray3!( array3, parameters )
end

update!((1,2,3))

 array1 = [7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0] 
 array2 = [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0] 
 array3 = [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]

```

and

```julia
@btime update!((1,2,3))
  25.000 ns (0 allocations: 0 bytes)

```
