# Why \`mean\` with \`dims\` argument is so slow?

**URL:** https://discourse.julialang.org/t/why-mean-with-dims-argument-is-so-slow/41105
**Category:** Performance
**Tags:** question
**Created:** [June 10, 2020, 1:15am UTC](https://discourse.julialang.org/t/why-mean-with-dims-argument-is-so-slow/41105 "2020-06-10T01:15:08Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)
#### Post date: [June 10, 2020, 1:15am UTC](https://discourse.julialang.org/t/why-mean-with-dims-argument-is-so-slow/41105/1 "2020-06-10T01:15:08Z")

</div>

Consider:

```julia
using BenchmarkTools, Statistics
A = randn(4,3,2);
@btime mean($A; dims=1);
# 90.184 ns (1 allocation: 128 bytes)
@btime mean($A);
# 9.891 ns (0 allocations: 0 bytes)

```

That’s a 10x factor difference! Is there a way to improve over this? A faster way to compute `mean` along a dimension?

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [June 10, 2020, 1:28am UTC](https://discourse.julialang.org/t/why-mean-with-dims-argument-is-so-slow/41105/2 "2020-06-10T01:28:27Z")

</div>

Consider:

```julia
julia> A = randn(400,300,200);
julia> using BenchmarkTools
julia> @btime mean($A; dims=1);
  9.917 ms (2 allocations: 468.83 KiB)
julia> @btime mean($A);
  9.615 ms (0 allocations: 0 bytes)

```

Nanosseconds measures are bullshit.

---

<div class="post-metadata">

### Author: ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)
#### Post date: [June 10, 2020, 3:11am UTC](https://discourse.julialang.org/t/why-mean-with-dims-argument-is-so-slow/41105/3 "2020-06-10T03:11:04Z")

</div>

> [@Henrique\_Becker](#):
>
> Nanosseconds measures are bullshit.

Perhaps it would be a bit more accurate to say that nanosecond measurements are very delicate because you can very easily end up measuring something other than what you intended to measure. I believe this is what is happening in the benchmark reported by the OP: `mean(A)` returns a scalar and so it is allocation-free, while `mean(A, dims=1)` returns a vector and so it must perform at least one allocation, and this allocation ends up dominating the overall runtime.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [June 10, 2020, 5:21am UTC](https://discourse.julialang.org/t/why-mean-with-dims-argument-is-so-slow/41105/4 "2020-06-10T05:21:59Z")

</div>

> [@e3c6](#):
>
> That’s a 10x factor difference!

Well, it’s an 80 ns difference. You can avoid some of it by pre-allocating the output in the shape you want:

```Julia
julia> using BenchmarkTools, Statistics

julia> A = randn(4,3,2);

julia> @btime mean($A; dims=1);
  101.318 ns (1 allocation: 128 bytes)

julia> @btime mean($A);
  10.427 ns (0 allocations: 0 bytes)

julia> m = zeros(1, 3, 2);

julia> @btime mean!($m, $A);
  62.747 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

### Author: ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)
#### Post date: [June 10, 2020, 12:15pm UTC](https://discourse.julialang.org/t/why-mean-with-dims-argument-is-so-slow/41105/5 "2020-06-10T12:15:16Z")

</div>

Oh, I should have tested on larger matrices!
