# Loops, allocations and helping the coder

**URL:** <https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733>\
**Category:** Internals & Design\
**Created:** [October 8, 2023, 6:18pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733 "2023-10-08T18:18:05Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [October 10, 2023, 2:34pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733/21 "2023-10-10T14:34:38Z")

</div>

A variant of this idea has been implemented as a stdlib in .NET. See [ArrayPool\<T\> Class (System.Buffers) | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/api/system.buffers.arraypool-1?view=net-7.0) for the API and [Pooling large arrays with ArrayPool – Adam Sitnik – .NET Performance and Reliability](https://adamsitnik.com/Array-Pool/) for an explainer.

---

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [October 10, 2023, 3:57pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733/22 "2023-10-10T15:57:25Z")

</div>

> [@Tamas\_Papp](#):
>
> parallel threads so that each gets to use one work buffer one at a time

This is a particular pain I keep running into.

---

<div class="post-metadata">

**Author:** ![maxfreu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxfreu/32/17468_2.png) [@maxfreu](https://discourse.julialang.org/u/maxfreu)\
**Post date:** [October 10, 2023, 4:08pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733/23 "2023-10-10T16:08:28Z")

</div>

@Mason at the first glance, Bumper.jl reminds me of [arena allocators](https://www.rfleury.com/p/untangling-lifetimes-the-arena-allocator) - are they conceptually related or even equivalent?

---

<div class="post-metadata">

**Author:** ![Paul\_Soderlind](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paul_soderlind/32/1753_2.png) [@Paul\_Soderlind](https://discourse.julialang.org/u/Paul_Soderlind)\
**Post date:** [October 10, 2023, 7:29pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733/24 "2023-10-10T19:29:00Z")

</div>

Thanks for taking part in this thread. I learned some news things, but I also think the discussion turned rather technical and somehow disregarded the usage patterns of less CS-savvy Julia users.

If I may, I would like to get back to the original issue. Background: (a) allocations cause performance problems; (b) many (most?) Julia users want to write simple, but yet reasonably performant, code.

If the “compiler” could help with that, I believe it would be a great selling point for Julia.

I currently hear students and colleagues saying that it’s easier to get performance (from simple code) in other languages and that Julia is “hard” to squeeze out performance from. It would be nice to prove them otherwise.

---

<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:** [October 10, 2023, 8:25pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733/25 "2023-10-10T20:25:00Z")

</div>

> [@Paul\_Soderlind](#):
>
> If the “compiler” could help with that, I believe it would be a great selling point for Julia.

The issue is that the compiler, in Julia, sometimes does not have some information that the compiler in other (compiled) languages, has. For instance, a simple fortran code like this:

```fortran
! main calls foo 100 times
program main
    double precision :: x
    do i = 1, 100
        call foo(x)
    end do
    print *, x
end program main

! foo requires a y array of 100 elements
subroutine foo(x) 
    integer :: i
    double precision :: x, y(100)
    do i = 1, 100
        y(i) = 1.0
        x = x + y(i)
    end do
end subroutine foo

```

The function `foo` is called within a loop, and inside it it requires a vector `y` of length 100. When this code is compiled, as a whole, a single instance of `y` is created and will be reused. That can happen because the compiler knows in advance how `foo` is called from within `main`.

In Julia a similar result requires allocating the array `y` outside `foo`, and either having it as a global constant buffer, or passing it always as a parameter, because the compiler does not have the information, in advance, on how `foo` will be used every time, so that it cannot reuse the buffer on every call to foo.

These are the cases where it seems simpler to obtain a performant code in other language than in Julia.

In this specific cases I think it is fair to say that other languages, like fortran, are easier to tune for performance.

But… this is very limited. Most times, even a compiled language like fortran, you have to resize the auxiliary arrays depending on the input. In these cases, we need to deal with global buffers (through shared modules, for instance in Fortran) or pass explicitly the auxiliary arrays as parameters to the inner functions. Just like in Julia. Since the compiler cannot help much even in static languages, I doubt much can be done in Julia to improve on this (except improving escape analysis, but this won’t solve the issue for large buffers if they have to be recreated on every function call).

If you have concurrent access to buffers, like the use of the Channels above, at least in Fortran your life would be much harder than in Julia, but then I guess we are talking of of more advanced features.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 10, 2023, 9:04pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733/26 "2023-10-10T21:04:06Z")

</div>

> [@maxfreu](#):
>
> @Mason at the first glance, Bumper.jl reminds me of [arena allocators](https://www.rfleury.com/p/untangling-lifetimes-the-arena-allocator) - are they conceptually related or even equivalent?

Arena allocator is another name for a bump allocator (the namesake of Bumper.jl) so yeah it’s the exact same concept.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 10, 2023, 9:10pm UTC](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733/27 "2023-10-10T21:10:12Z")

</div>

> [@Paul\_Soderlind](#):
>
> If the “compiler” could help with that, I believe it would be a great selling point for Julia.

Julia’s compiler is actually somewhat uniquely bad at helping with this sort of thing currently, and that’s why arrays need to be dealt with more consciously than in many other languages. However, there is definitely work happening right now in the compiler infrastructure that will greatly help with this use case. E.g. [https://github.com/JuliaLang/julia/pull/51319](https://github.com/JuliaLang/julia/pull/51319) will give some modest speedups to intermediate array allocation, but will also be an important step towards us being able to teach the compiler how to better understand and optimize array allocations (like what we do with normal mutable structs)

[Previous page](https://discourse.julialang.org/t/loops-allocations-and-helping-the-coder/104733.md?page=1)
