# Way to return the number of allocations?

**URL:** <https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167>\
**Category:** General Usage\
**Created:** [August 1, 2017, 4:22pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167 "2017-08-01T16:22:53Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [August 1, 2017, 4:22pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/1 "2017-08-01T16:22:53Z")

</div>

Is there a way to return the number of allocations used in a code? For example, I want to get the number `5` of the `5 allocations` in the following example:

```julia
julia> using BenchmarkTools

julia> @btime [1,1,1]+[2,2,2]+[3,3,3];
  193.087 ns (5 allocations: 560 bytes)

```

The purpose of this is to create a unit test that checks the number of allocations consumed in a specific function. This is a performance-critical function, so I want to keep the number of allocations minimal, but sometimes updating this function accidentally increases the number of allocations. I want to detect such a case automatically by writing a unit test like

```julia
@test @numallocs(myfunction()) ≤ 2

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 1, 2017, 4:37pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/2 "2017-08-01T16:37:39Z")

</div>

Try this:

```julia
macro numallocs(expr)
    return quote
        n1 = Base.gc_num()
        $(esc(expr))
        n2 = Base.gc_num()
        diff = Base.GC_Diff(n2, n1)
        Base.gc_alloc_count(diff)
    end
end

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 1, 2017, 4:42pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/3 "2017-08-01T16:42:51Z")

</div>

Hmm `BenchmarkTools` compute this like: [https://github.com/JuliaCI/BenchmarkTools.jl/blob/1238af0326a13f44c2121a017a13e7ef327bddf6/src/execution.jl#L306](https://github.com/JuliaCI/BenchmarkTools.jl/blob/1238af0326a13f44c2121a017a13e7ef327bddf6/src/execution.jl#L306). Not sure if that is more accurate.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 1, 2017, 4:53pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/4 "2017-08-01T16:53:49Z")

</div>

`@timed` should give you that:

```julia
z = @timed sin.([x for x in 1:1000]);
z[1] # result
z[2] # elapsed time
z[3] # total number of bytes allocated
...

```

---

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [August 1, 2017, 5:23pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/5 "2017-08-01T17:23:49Z")

</div>

Thanks, @kristoffer.carlsson and @anon94023334! The methods suggested by you two return larger numbers of allocations than `@btime`. However, from the `BenchmarkTools` code that @kristoffer.carlsson referred to, it was easy to create the wanted macro by copying the `@btime` code:

```julia
macro nallocs(args...)
    _, params = BenchmarkTools.prunekwargs(args...)
    quote
        tmp = @benchmarkable $(map(esc,args)...)
        warmup(tmp)
        $(BenchmarkTools.hasevals(params) ? :() : :(BenchmarkTools.tune!(tmp)))
        b, val = BenchmarkTools.run_result(tmp)
        bmin = minimum(b)
        a = allocs(bmin)
    end
end

```

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 1, 2017, 5:24pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/6 "2017-08-01T17:24:29Z")

</div>

You need to precompile the function first by running it once, then run `@timed`. `@btime` does this for you.

---

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [August 1, 2017, 5:30pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/7 "2017-08-01T17:30:30Z")

</div>

> [@anon94023334](#):
>
> You need to precompile the function first by running it once, then run @timed. @btime does this for you.

I expected so, too, but running `@timed [1,1,1]+[2,2,2]+[3,3,3]` the second time still reports 9 allocations, whereas `@btime` reports 5 allocations. To me 5 allocations makes more sense, because it takes one allocation for each array construction and one for each addition. Provided that 5 allocations is the correct result, is there a way to make `@timed` to report 5 allocations for this code?

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 1, 2017, 5:33pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/8 "2017-08-01T17:33:02Z")

</div>

`@time` agrees (perhaps not surprisingly) with `@timed`. This is a simple function; perhaps someone who’s better at this sort of thing can take a look at `@code_llvm` or `@code_native` and see what the correct value is.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 1, 2017, 5:38pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/9 "2017-08-01T17:38:53Z")

</div>

If you just want to know the number of allocations, why would you run a benchmark on the function, calling it potentially thousand of times?

---

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [August 1, 2017, 5:55pm UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/10 "2017-08-01T17:55:04Z")

</div>

> [@kristoffer.carlsson](#):
>
> If you just want to know the number of allocations, why would you run a benchmark on the function, calling it potentially thousand of times?

Good point. I would love to know how to use one of the above suggested methods to get the exactly same number of allocations as `@btime` while running the code only twice internally.

Plus, I need a capability to interpolate variables using `$` (which is supported by `@btime`), because the functions I would like to test take arguments and I don’t want to count the number of allocations consumed in constructing those arguments. Not sure which part of the `@btime` code handles interpolation…

EDIT: OK, using `@nallocs` slows down the unit test significantly. I definitely need a better solution! Any suggestions?

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [August 2, 2017, 2:01am UTC](https://discourse.julialang.org/t/way-to-return-the-number-of-allocations/5167/11 "2017-08-02T02:01:56Z")

</div>

You can eliminate some extra allocations (“effects of compilation”) by wrapping Kristoffer’s solution (in the manner of `@allocated` in Base):

```julia
macro numalloc(expr)
    return quote
        let
            local f
            function f()
                n1 = Base.gc_num()
                $(esc(expr))
                n2 = Base.gc_num()
                diff = Base.GC_Diff(n2,n1)
                Base.gc_alloc_count(diff)
            end
            f()
        end
    end
end

```

Handling interpolations looks to be nontrivial.
