# Allocations when moving loop into a function

**URL:** <https://discourse.julialang.org/t/allocations-when-moving-loop-into-a-function/129534>\
**Category:** New to Julia\
**Tags:** memory-allocation\
**Created:** [June 1, 2025, 6:19pm UTC](https://discourse.julialang.org/t/allocations-when-moving-loop-into-a-function/129534 "2025-06-01T18:19:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![omicron8](https://avatars.discourse-cdn.com/v4/letter/o/85f322/32.png) [@omicron8](https://discourse.julialang.org/u/omicron8)\
**Post date:** [June 1, 2025, 6:19pm UTC](https://discourse.julialang.org/t/allocations-when-moving-loop-into-a-function/129534/1 "2025-06-01T18:19:23Z")

</div>

Why does the first variant (function foo) allocate a large amount of memory while the second variant (function bar) does not? The difference is whether the loop is inside or outside the function. Is there a way to have the loop outside without so many allocations?

```julia
using BenchmarkTools

function foo!(F, A)
  F[1] = A[2]
  F[2] = - A[1]
  return nothing
end

function bar!(F, A)
  for i = 1:size(A,1)
    F[i,1] = A[i,2]
    F[i,2] = -A[i,1]
  end
  return nothing
end

n = 15_000
A = rand(n,2)
F = similar(A)

@btime begin
  for i = 1:n
    @views foo!((F[i, :]), (A[i, :]))
  end
end

@btime begin
  bar!(F, A)
end

```

Reults:  
6.409 ms (161935 allocations: 3.62 MiB)  
4.062 μs (0 allocations: 0 bytes)

---

<div class="post-metadata">

**Author:** ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)\
**Post date:** [June 1, 2025, 7:15pm UTC](https://discourse.julialang.org/t/allocations-when-moving-loop-into-a-function/129534/2 "2025-06-01T19:15:06Z")

</div>

Hi, and welcome to the Julia community!

The problem is that in

```julia
@btime begin
  for i = 1:n
    @views foo!((F[i, :]), (A[i, :]))
  end
end

```

`n` is a (non-`const`, non-typed) global variable, meaning the compiler doesn’t know its type, nor that of `i`. So in every iteration we need to check the types involved. The same is true for `A` and `F`. If you declare them all `const` (note that this still allows in-place mutation of the `Array`s), I get

```julia
julia> @btime begin
  for i = 1:n
    @views foo!((F[i, :]), (A[i, :]))
  end
end
  13.000 μs (0 allocations: 0 bytes)

```

Alternatively, BenchmarkTools.jl also allows for interpolating global variables using `$`:

```julia
julia> ... # non-const n, A, F

julia> @btime begin
           for i = 1:$n
               @views foo!(($F[i, :]), ($A[i, :]))
             end
         end
  11.000 μs (0 allocations: 0 bytes)

```

I’m not sure why we don’t need such interpolation for `bar!`, though. But even if we did, we only need to determine the types of `F` and `A` once, instead of once in every iteration, so the timing and allocation difference between the interpolated and non-interplated version would be much less pronounced.

---

<div class="post-metadata">

**Author:** ![omicron8](https://avatars.discourse-cdn.com/v4/letter/o/85f322/32.png) [@omicron8](https://discourse.julialang.org/u/omicron8)\
**Post date:** [June 1, 2025, 7:49pm UTC](https://discourse.julialang.org/t/allocations-when-moving-loop-into-a-function/129534/3 "2025-06-01T19:49:32Z")

</div>

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 1, 2025, 10:04pm UTC](https://discourse.julialang.org/t/allocations-when-moving-loop-into-a-function/129534/4 "2025-06-01T22:04:08Z")

</div>

Keep in mind you probably want everything where performance matters to be in a function, because it’s not compiled otherwise. See the Performance tips for more such suggestions:

- [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/)

Actually, maybe even take a look at the in-development version of the Performance tips, as they have a better structure:

- [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1.13-dev/manual/performance-tips/)
