# What does 0 allocations: #=nonzero=# bytes mean?

**URL:** <https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997>\
**Category:** General Usage\
**Tags:** benchmarktools\
**Created:** [April 12, 2025, 6:12am UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997 "2025-04-12T06:12:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [April 12, 2025, 6:12am UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997/1 "2025-04-12T06:12:41Z")

</div>

Sometimes BenchmarkTools reports 0 allocations but the number of bytes isn’t 0. It can vary between runs. What does that mean?

```julia
julia> using BenchmarkTools

julia> foo() = rand((1.3, 1))
foo (generic function with 1 method)

julia> @btime foo()
  18.938 ns (0 allocations: 7 bytes)
1.3

julia> @btime foo()
  19.157 ns (0 allocations: 6 bytes)
1

julia> @btime foo()
  19.238 ns (0 allocations: 7 bytes)
1

```

---

<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:** [April 12, 2025, 7:37am UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997/2 "2025-04-12T07:37:52Z")

</div>

Maybe it’s some kind of average? `@allocated foo()` for me always returns either 0 (when returning 1) or 16 (when returning 1.3).  
I understand that it allocates due to the uncertain return type, but why only when returning 1.3?

---

<div class="post-metadata">

**Author:** ![fgerick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fgerick/32/13228_2.png) [@fgerick](https://discourse.julialang.org/u/fgerick)\
**Post date:** [April 12, 2025, 8:38am UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997/3 "2025-04-12T08:38:30Z")

</div>

I guess it is because `foo() = rand((1.3, 1))` is not type stable, `foo2() = rand((1.3, 1.0))` is and does not allocate.

Chairmarks.jl actually does show why BenchmarkTools.jl shows 0 allocations:

```julia
julia> @b foo()
21.483 ns (0.45 allocs: 7.233 bytes)

```

It’s rounding to 0.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [April 12, 2025, 8:50am UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997/4 "2025-04-12T08:50:19Z")

</div>

As explained, the allocs are because of type instability - the return value is being boxed, which normally requires an allocation.

My guess is that there is a cache of pre-boxed small integers somewhere, so that case doesn’t allocate.

---

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [April 12, 2025, 9:52am UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997/5 "2025-04-12T09:52:40Z")

</div>

Yes Julia has a cache of boxed small ints -512:512 I believe.

---

<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:** [April 12, 2025, 9:56am UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997/6 "2025-04-12T09:56:19Z")

</div>

Empirically, I can confirm that `rand((1.3, n))` for `n` in [-512, 511] indeed does not allocate when returning `n`, and does for other `Int` values of `n`.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [April 12, 2025, 6:03pm UTC](https://discourse.julialang.org/t/what-does-0-allocations-nonzero-bytes-mean/127997/7 "2025-04-12T18:03:36Z")

</div>

Rounding down because one case was preallocated makes sense. This is what happens for non-`Int`s, which implies rounding of a fractional bytes estimate that I still don’t really get:

```julia
julia> foo() = rand((1.3, 1im))
foo (generic function with 2 methods)

julia> @btime foo()
  26.780 ns (1 allocation: 23 bytes)
1.3

julia> @btime foo()
  26.633 ns (1 allocation: 23 bytes)
0 + 1im

julia> @b foo()
64.078 ns (1 allocs: 22.576 bytes)

julia> @b foo()
77.885 ns (1 allocs: 22.513 bytes)

```

More importantly, does anyone know why there seems to be actually 0 allocations for a similar type-unstable method that doesn’t use `rand`? Squinting at the `@code_llvm` suggested to me both methods store `1.3` and `1im` as hidden globals.

```julia
julia> foo(x, y) = x > y ? 1.3 : 1im
foo (generic function with 2 methods)

julia> @btime foo($3, $5)
  2.600 ns (0 allocations: 0 bytes)
0 + 1im

julia> @b foo(3, 5)
1.178 ns

julia> Base.return_types(foo, typeof.((3, 5)))
1-element Vector{Any}:
 Union{Complex{Int64}, Float64}

julia> Base.return_types(foo, ())
1-element Vector{Any}:
 Union{Complex{Int64}, Float64}

```
