# Common allocation mistakes

**URL:** <https://discourse.julialang.org/t/common-allocation-mistakes/66127>\
**Category:** Performance\
**Tags:** memory-allocation\
**Created:** [August 10, 2021, 12:08pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127 "2021-08-10T12:08:19Z")\
**Posts on this page:** 8\
**Page:** 3

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [June 28, 2023, 1:29pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/41 "2023-06-28T13:29:31Z")

</div>

> [@lmiq](#):
>
> `*(x)` is not a defined operation

```julia
julia> *(2)
2

julia> @descend *(2)
[ Info: tracking Base
*(x::Number) @ Base ~/packages/julias/julia-1.9/share/julia/base/operators.jl:516
[ Info: This method only fills in default arguments; descend into the body method to see the full source.
516 *(x::Int64::Number)::Int64 = x
[...]

```

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [June 28, 2023, 1:37pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/42 "2023-06-28T13:37:26Z")

</div>

You are right. The problem is `reduce` that apply the operation one element at the time:

```julia
julia> x = rand(5); y = rand(5);

julia> temp1 = x .* y
5-element Vector{Float64}:
 0.021011105122337788
 0.18748492243282094
 0.29715362865317285
 0.02001732616845591
 0.5826489054162168

julia> z1 = norm(temp1)
0.6810086504806679

julia> z2 = norm(xi*yi for (xi,yi) in zip(x,y))
0.6810086504806679

julia> z1 == z2
true

julia> temp3 = map(*,x,y)
5-element Vector{Float64}:
 0.021011105122337788
 0.18748492243282094
 0.29715362865317285
 0.02001732616845591
 0.5826489054162168

julia> temp3 == temp1
true

julia> z3 = reduce(norm,temp3)
0.021011105122337788

julia> z4 = norm(norm(norm(norm(temp3[1],temp3[2]),temp3[3]),temp3[4]),temp3[5])
0.021011105122337788

julia> z3 == z4
true

```

The correct version in this case is:

```julia
function f2(x,y)
    z = 0.
    for i in 1:10
      z += sum( xi^2 * yi^2 for (xi,yi) in zip(x,y)) |> sqrt 
    end
    z
end

```

This doesn’t allocate but of course it is specific to the toy example.

---

<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:** [June 28, 2023, 2:59pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/43 "2023-06-28T14:59:53Z")

</div>

> [@jishnub](#):
>
> ```julia
> julia> *(2)
> 2
> 
> ```

Hehe, why is that defined at all?

---

<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 28, 2023, 5:05pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/44 "2023-06-28T17:05:26Z")

</div>

I was also confused until trying:

```julia
julia> +(1)
1

julia> *(1)
1

julia> ^(1)
ERROR: MethodError: no method matching ^(::Int64)
Closest candidates are:
  ^(::Number, ::Missing) at missing.jl:124
  ^(::Number, ::Rational) at rational.jl:481
  ^(::T, ::Complex{T}) where T<:Real at complex.jl:852
  ...
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

julia> +(1, 2, 3)
6

julia> *(1, 2, 3)
6

```

This is described in this footnote here: [Mathematical Operations and Elementary Functions · The Julia Language](https://docs.julialang.org/en/v1/manual/mathematical-operations/#citeref-2)

> The operators +, ++ and \* are non-associative. a + b + c is parsed as +(a, b, c) not +(+(a, b), c). However, the fallback methods for +(a, b, c, d…) and \*(a, b, c, d…) both default to left-associative evaluation.

In other words, `+` and `*` are not truly binary operators like `^`.

---

<div class="post-metadata">

**Author:** ![sob](https://avatars.discourse-cdn.com/v4/letter/s/65b543/32.png) [@sob](https://discourse.julialang.org/u/sob)\
**Post date:** [June 29, 2023, 12:09pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/45 "2023-06-29T12:09:23Z")

</div>

For those who have extensive experience with `StaticArrays`: as you increase the number of elements, at what point do you see a decrease in performance? The documentation says 100, but I’m curious what people’s real life experience suggests.

---

<div class="post-metadata">

**Author:** ![IlianPihlajamaa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilianpihlajamaa/32/28766_2.png) [@IlianPihlajamaa](https://discourse.julialang.org/u/IlianPihlajamaa)\
**Post date:** [August 20, 2023, 7:57pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/46 "2023-08-20T19:57:57Z")

</div>

You can try to run this code [https://github.com/JuliaArrays/StaticArrays.jl/blob/master/perf/README\_benchmarks.jl](https://github.com/JuliaArrays/StaticArrays.jl/blob/master/perf/README_benchmarks.jl)

For different sizes ‘N’. I expect the result is highly machine specific but im interested in what you find.

---

<div class="post-metadata">

**Author:** ![sob](https://avatars.discourse-cdn.com/v4/letter/s/65b543/32.png) [@sob](https://discourse.julialang.org/u/sob)\
**Post date:** [August 20, 2023, 10:57pm UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/47 "2023-08-20T22:57:39Z")

</div>

So this is what I get for 3 and 10:

```julia
julia> simple_bench(3)
============================================
    Benchmarks for 3×3 Float64 matrices
============================================
Matrix multiplication -> 9.3x speedup
Matrix multiplication (mutating) -> 1.4x speedup
Matrix addition -> 22.2x speedup
Matrix addition (mutating) -> 1.7x speedup
Matrix determinant -> 87.9x speedup
Matrix inverse -> 82.3x speedup
Matrix symmetric eigendecomposition -> 4.4x speedup
Matrix Cholesky decomposition -> 12.3x speedup
Matrix LU decomposition -> 7.1x speedup
Matrix QR decomposition -> 61.8x speedup

julia> simple_bench(10)
============================================
    Benchmarks for 10×10 Float64 matrices
============================================
Matrix multiplication -> 3.8x speedup
Matrix multiplication (mutating) -> 2.4x speedup
Matrix addition -> 6.1x speedup
Matrix addition (mutating) -> 2.0x speedup
Matrix determinant -> 1.5x speedup
Matrix inverse -> 1.8x speedup
Matrix symmetric eigendecomposition -> 1.0x speedup
Matrix Cholesky decomposition -> 3.4x speedup
Matrix LU decomposition -> 1.5x speedup
Matrix QR decomposition -> 17.7x speedup

julia> versioninfo()
Julia Version 1.10.0-beta2
Commit a468aa198d0 (2023-08-17 06:27 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 16 × AMD Ryzen 7 4800U with Radeon Graphics
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, znver2)
  Threads: 23 on 16 virtual cores
Environment:
  LD_LIBRARY_PATH = /home/***/lib/

```

I started N=100 3 hours ago and it’s not done yet. So that answers that.

---

<div class="post-metadata">

**Author:** ![IlianPihlajamaa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilianpihlajamaa/32/28766_2.png) [@IlianPihlajamaa](https://discourse.julialang.org/u/IlianPihlajamaa)\
**Post date:** [August 21, 2023, 5:42am UTC](https://discourse.julialang.org/t/common-allocation-mistakes/66127/48 "2023-08-21T05:42:20Z")

</div>

Yes, for N=100, you are asking the compiler to basically write out matrix methods for 10000-element matrices 😉

[Previous page](https://discourse.julialang.org/t/common-allocation-mistakes/66127.md?page=2)
