# Unwanted allocations when updating type field

**URL:** <https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122>\
**Category:** Performance\
**Tags:** question\
**Created:** [July 12, 2022, 8:16pm UTC](https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122 "2022-07-12T20:16:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![WDM-Computation](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wdm-computation/32/34681_2.png) [@WDM-Computation](https://discourse.julialang.org/u/WDM-Computation)\
**Post date:** [July 12, 2022, 8:16pm UTC](https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122/1 "2022-07-12T20:16:23Z")

</div>

Hello! Physics PhD student here using Julia for a research project.

I have a question regarding what seems to be unnecessary extra memory allocations in my program.

I am using a custom type along the lines of

```julia
abstract type SuperType end

mutable struct MyStruct <: SuperType
           A::Vector{Float64}
end

```

As the program runs, I want to update the values the field A for the instances of MyStruct, e.g.

```julia
S = MyStruct([0., 0., 0.])

@time S.A = [1,1,1]

```

Which shows 2 allocations for a total of 160 bytes. While this is not an issue for a few updates, my program involves updating these fields thousands to millions of times per run.

Any insight is appreciated!

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [July 12, 2022, 8:21pm UTC](https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122/2 "2022-07-12T20:21:28Z")

</div>

An alternative would be to make your vector field immutable and to update it elementwise using broadcasting:

```julia
using BenchmarkTools

mutable struct MyMutableStruct
    A::Vector{Float64}
end

struct MyImmutableStruct
    A::Vector{Float64}
end

n = 10_000
S1 = MyMutableStruct(ones(n));
S2 = MyImmutableStruct(ones(n));
new_A = ones(n);
@btime $S1.A .= $new_A;
@btime $S2.A .= $new_A;

```

---

<div class="post-metadata">

**Author:** ![WDM-Computation](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wdm-computation/32/34681_2.png) [@WDM-Computation](https://discourse.julialang.org/u/WDM-Computation)\
**Post date:** [July 12, 2022, 8:27pm UTC](https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122/3 "2022-07-12T20:27:54Z")

</div>

I am surprised that we can update the values in S2, as it’s an immutable type. Is this mutability just in reference to the fields the type holds, not the values in said fields? Or does this syntax have to do with BenchmarkTools perhaps?

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [July 12, 2022, 8:28pm UTC](https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122/4 "2022-07-12T20:28:41Z")

</div>

Yes, exactly. It will always reference the address of the same vector in memory, but the elements of this vector can change

---

<div class="post-metadata">

**Author:** ![WDM-Computation](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wdm-computation/32/34681_2.png) [@WDM-Computation](https://discourse.julialang.org/u/WDM-Computation)\
**Post date:** [July 12, 2022, 8:43pm UTC](https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122/5 "2022-07-12T20:43:53Z")

</div>

When using " $ " in $S1.A, etc., is this akin to @view for referring to the memory values?

---

<div class="post-metadata">

**Author:** ![MatFi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/matfi/32/10002_2.png) [@MatFi](https://discourse.julialang.org/u/MatFi)\
**Post date:** [July 12, 2022, 8:55pm UTC](https://discourse.julialang.org/t/unwanted-allocations-when-updating-type-field/84122/6 "2022-07-12T20:55:30Z")

</div>

I think the `$` is needed because the benchmak is done in global scope.  
see [https://github.com/JuliaCI/BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl):

> If the expression you want to benchmark depends on external variables, you should use [`$` to “interpolate”](https://juliaci.github.io/BenchmarkTools.jl/stable/manual/#Interpolating-values-into-benchmark-expressions) them into the benchmark expression to [avoid the problems of benchmarking with globals](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-global-variables). Essentially, any interpolated variable `$x` or expression `$(...)` is “pre-computed” before benchmarking begins:

```julia
julia> A = rand(3,3);

julia> @btime inv($A); # we interpolate the global variable A with $A
  1.191 μs (10 allocations: 2.31 KiB)

julia> @btime inv($(rand(3,3))); # interpolation: the rand(3,3) call occurs before benchmarking
  1.192 μs (10 allocations: 2.31 KiB)

julia> @btime inv(rand(3,3)); # the rand(3,3) call is included in the benchmark time
  1.295 μs (11 allocations: 2.47 KiB)

```
