# \[ANN\] ArenaPirate.jl: proof-of-concept arena allocator (not in the registry)

**URL:** <https://discourse.julialang.org/t/ann-arenapirate-jl-proof-of-concept-arena-allocator-not-in-the-registry/132856>\
**Category:** Package Announcements\
**Tags:** memory-allocation\
**Created:** [October 3, 2025, 3:20pm UTC](https://discourse.julialang.org/t/ann-arenapirate-jl-proof-of-concept-arena-allocator-not-in-the-registry/132856 "2025-10-03T15:20:35Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![artemsolod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/artemsolod/32/20704_2.png) [@artemsolod](https://discourse.julialang.org/u/artemsolod)\
**Post date:** [October 3, 2025, 3:20pm UTC](https://discourse.julialang.org/t/ann-arenapirate-jl-proof-of-concept-arena-allocator-not-in-the-registry/132856/1 "2025-10-03T15:20:35Z")

</div>

repo: [https://github.com/artemsolod/ArenaPirate.jl](https://github.com/artemsolod/ArenaPirate.jl)

This package redefines `Memory{T}(::UndefInitializer, m::Int64)` (hence “pirate” in the name) and provides an `@arena` macro for marking sections of code to be eligible for arena allocation. Large enough allocations of `Memory{T}` with `isbitstype(T)` get arena allocated provided arena has sufficient remaining capacity. Standard julia allocation is used as fallback. I’ve been playing with this for a couple of weeks and found it quite useful in GC-bound workloads.

Here is a comparison of timings for calling `f(x) = median(x)` vs `f_arena(x) = @arena f(x)` on a 10 mln element vector and repeated calls (32 runs: single and multithreaded on 8 threads – see `examples/medians.jl`). Note that the `Statistics.median` function is allocating and is not `@arena`-aware.

```julia-auto
____ Built-in allocator benchmarks:
  0.154144 seconds (18 allocations: 78.262 MiB, 16.38% gc time) # single call
  4.363108 seconds (298 allocations: 2.446 GiB, 6.95% gc time) # 32 repeated calls
  1.384049 seconds (340 allocations: 2.446 GiB, 25.96% gc time) # 32 calls using Threads.@threads
____ Arena benchmarks:
  0.072805 seconds (55 allocations: 2.000 KiB) # single call (@arena)
  2.346896 seconds (747 allocations: 17.250 KiB) # 32 repeated calls (@arena)
  0.413609 seconds (810 allocations: 21.562 KiB) # 32 calls using Threads.@threads (@arena)

```

I would like to hear your feedback: ideas for performance improvements, bug reports, interface improvements. And especially how it can be extended, i.e. what are all arena-allocatable things?
