# Why does this matrix increment allocate?

**URL:** <https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796>\
**Category:** New to Julia\
**Tags:** memory-allocation\
**Created:** [February 20, 2022, 11:31am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796 "2022-02-20T11:31:02Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [February 20, 2022, 11:31am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/1 "2022-02-20T11:31:02Z")

</div>

```julia
module somemodule

using BenchmarkTools

struct MyType
    A::AbstractMatrix
    B::AbstractMatrix
end

myinc(A::AbstractMatrix, B::AbstractMatrix) = A .+= B
mytypeinc(t::MyType, B::AbstractMatrix) = t.A .+= B
mytypeinc2(t::MyType, B::AbstractMatrix) = myinc(t.A, B)

function perf()
    H = [1.0 0 ; 1.0 -1.0];
    Q = [0.01 0 ; 0 0.01];
    t = MyType(H, Q);

    @btime myinc($H, $Q)
    @btime mytypeinc($t, $Q)
    @btime mytypeinc2($t, $Q)
end

perf()

end

```

This outputs

```julia
  20.435 ns (0 allocations: 0 bytes)
  445.258 ns (2 allocations: 64 bytes)
  28.728 ns (0 allocations: 0 bytes)

```

Initially I had implemented in my code something like `mytypeinc`, I was surprised to see that it allocates, eventually tried `myinc` and that doesn’t allocate. So I tried to write an “improved” version of `mytypeinc` called `mytypeinc2` which just calls `myinc`, and that works to avoid the allocation. But why is it that such a workaround is necessary? Why doesn’t `mytypeinc` do the obvious right thing? Clearly my mental model is missing something crucial.

```julia
julia> versioninfo()
Julia Version 1.7.2
Commit bf53498635 (2022-02-06 15:21 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, haswell)
Environment:
  JULIA_EDITOR = "/home/me/.vscode-server/bin/7db1a2b88f7557e0a43fec75b6ba7e50b3e9f77e/node"
  JULIA_NUM_THREADS = 

```

---

<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:** [February 20, 2022, 11:37am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/2 "2022-02-20T11:37:01Z")

</div>

> [@freeman](#):
>
> `A::AbstractMatrix`

Probably because these are abstract containers. Use Matrix{T}, or a full parametric type.

---

<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:** [February 20, 2022, 11:39am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/3 "2022-02-20T11:39:07Z")

</div>

> [@freeman](#):
>
> `myinc` , and that works to avoid the allocation.

That is a function barrier, which allows the inner method to specialize

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [February 20, 2022, 11:39am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/4 "2022-02-20T11:39:58Z")

</div>

```julia
module somemodule

using BenchmarkTools

struct MyType{T}
    A::Matrix{T}
    B::Matrix{T}
end

myinc(A, B) = A .+= B
mytypeinc(t::MyType, B) = t.A .+= B
mytypeinc2(t::MyType, B) = myinc(t.A, B)

function perf()
    H = [1.0 0 ; 1.0 -1.0];
    Q = [0.01 0 ; 0 0.01];
    t = MyType{Float64}(H, Q);

    @btime myinc($H, $Q)
    @btime mytypeinc($t, $Q)
    @btime mytypeinc2($t, $Q)
end

perf()

end

```

```julia
  20.553 ns (0 allocations: 0 bytes)
  13.706 ns (0 allocations: 0 bytes)
  15.100 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [February 20, 2022, 11:41am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/5 "2022-02-20T11:41:51Z")

</div>

Thanks for the info, but what lesson should I take from here? (other than that I don’t understand abstract types and need to study them). That I should not make fields of structs abstract if I can avoid it?

For more context, my use case is very simple: I want to have a type which is a container for vectors and matrices, and I want to define on that type a specific pattern of linear algebra operations on those vectors and matrices, Given is, should I just make the change above to my type?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [February 20, 2022, 11:44am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/6 "2022-02-20T11:44:38Z")

</div>

You could also write:

```julia
struct MyType{T<:AbstractMatrix}
    A::T
    B::T
end

```

---

<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:** [February 20, 2022, 11:49am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/7 "2022-02-20T11:49:40Z")

</div>

> [@freeman](#):
>
> That I should not make fields of structs abstract if I can avoid it?

Yes, that is one important performance tip.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [February 21, 2022, 4:20am UTC](https://discourse.julialang.org/t/why-does-this-matrix-increment-allocate/76796/8 "2022-02-21T04:20:16Z")

</div>

See docs

[https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-type](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-type)

[https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-containers](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-containers)
