# Memory Pre-allocation in the global scope

**URL:** <https://discourse.julialang.org/t/memory-pre-allocation-in-the-global-scope/85861>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [August 17, 2022, 7:21am UTC](https://discourse.julialang.org/t/memory-pre-allocation-in-the-global-scope/85861 "2022-08-17T07:21:07Z")\
**Posts on this page:** 1\
**Showing post:** 19

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 17, 2022, 5:39pm UTC](https://discourse.julialang.org/t/memory-pre-allocation-in-the-global-scope/85861/19 "2022-08-17T17:39:27Z")

</div>

Let me try to summarize (because there is a lot of confusion around this):

1. **Your initial approach is fine in terms of performance.**  
“Avoid global variables” means avoid inheriting global variables through scoping. Your code will use global variables as inputs and outputs; this is normal.  
`F1!()` could have been defined without taking any arguments and still work. Then it would have to obtain the values from the outer (in this case global) scope. That would be bad practice and slow unless those variables are declared to be `const`. The `const` approach is intended for actual constants that are fixed across all simulations (none of your variables). It is useful because `const` variables are inherently known to all functions and are still fast to use. [Link](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Constants)

2. **You don’t need to allocate `R1` and `R2` in your example. Just call `rand` directly.**  
`F1!(V, P, G, i) = @. V[:,i] = rand()*(@view P[:,i]) + rand() * G`

3. **You could better organize your function inputs to be more readable.**

- Do not pass array sizes as arguments. `size` is very cheap to compute, so passing `n` and `N` alongside the arrays themselves just makes your code harder to read and more error prone. You should write the loop (no longer needed) as `for j in eachindex(G)`. Then you don’t need `n` at all: [link](https://discourse.julialang.org/t/why-and-when-to-pass-variables-to-sub-functions/49073).
- Some consider the type declarations unnecessary fluff: [link](https://www.oxinabox.net/2020/04/19/Julia-Antipatterns.html#over-constraining-argument-types). They don’t practically do anything besides document and throw better errors. This topic often causes [heated arguments](https://discourse.julialang.org/t/why-specify-argument-types-and-return-types/55567) though.
- A `setup` function for allocating the arrays would clean up your code, but it isn’t performance necessary.

```julia
function setup(n, N)
    V = zeros(Float64, n, N)
    P = zeros(Float64, n, N)
    G = zeros(Float64, n)
    return V, P, G
end
function compute!(V, P, G, i)
    @. V[:,i] = rand()*(@view P[:,i]) + rand() * G
end

n = 10
N = 100
i = 10
V, P, G = setup(n, N)
compute!(V, P, G, i)

```

- A custom type `struct` could further clean up your code. Though I personally think the previous version is good enough.

```julia
struct Parameters
    V::Matrix{Float64}
    P::Matrix{Float64}
    G::Vector{Float64}
end
function setup(n, N)
    V = zeros(Float64, n, N)
    P = zeros(Float64, n, N)
    G = zeros(Float64, n)
    return Parameters(V, P, G)
end
function compute!(data, i)
    @. data.V[:,i] = rand()*(@view data.P[:,i]) + rand() * data.G
end

n = 10
N = 100
i = 10
data = setup(n, N)
compute!(data, i)

```

- Typically in Julia, the `function` and `struct` definitions (top half of above code) would be stored in a separate package or file from the function calls (bottom half of above code) for better organization: [link](https://docs.julialang.org/en/v1/manual/code-loading/). Your original code has function and variable definitions all mixed together which makes it hard to read.

---

_[View the full topic](https://discourse.julialang.org/t/memory-pre-allocation-in-the-global-scope/85861)._
