# Mutable struct versus Base.RefValue

**URL:** <https://discourse.julialang.org/t/mutable-struct-versus-base-refvalue/38743>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 4, 2020, 3:06pm UTC](https://discourse.julialang.org/t/mutable-struct-versus-base-refvalue/38743 "2020-05-04T15:06:48Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbrea](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbrea/32/3879_2.png) [@jbrea](https://discourse.julialang.org/u/jbrea)\
**Post date:** [May 4, 2020, 3:06pm UTC](https://discourse.julialang.org/t/mutable-struct-versus-base-refvalue/38743/1 "2020-05-04T15:06:48Z")

</div>

For structures that contain among other things a mutable scalar, I see (at least) two approaches:

1. Make the structure mutable

```julia
mutable struct S1
    vector1::Vector{Float64}
    vector2::Vector{Float64}
    matrix::Matrix{Float64}
    scalar::Float64
end
set_scalar!(a::S1, x) = a.scalar = x
get_scalar(a::S1) = a.scalar

```

1. Use `Base.RefValue`

```julia
struct S2
    vector1::Vector{Float64}
    vector2::Vector{Float64}
    matrix::Matrix{Float64}
    scalar::Base.RefValue{Float64}
end
set_scalar!(a::S2, x) = a.scalar[] = x
get_scalar(a::S2) = a.scalar[]

```

The first approach looks a bit nicer to read (even though I would have kept the structure immutable without the scalar). But based on the following silly benchmark, the second approach seems a tiny bit faster.

```julia
f(a) = get_scalar(a) * sum(a.vector1) + sum(a.vector2) + sum(a.matrix)
g!(a, s) = a.vector1 .*= s
function do_something(a)
    b = prod(a.vector1) * prod(a.vector2)
    b += get_scalar(a)
    set_scalar!(a, .6)
    g!(a, .4)
    b *= get_scalar(a) + f(a)
    g!(a, 1/.4)
    set_scalar!(a, .4)
    b
end

x1 = S1([1., 2.], [3., 4.], [1. 2.; 5. 0.], .4)
x2 = S2([1., 2.], [3., 4.], [1. 2.; 5. 0.], Ref(.4))
using BenchmarkTools
julia> @btime do_something($x1)
  25.502 ns (0 allocations: 0 bytes)
398.20799999999997
julia> @btime do_something($x2)
  22.462 ns (0 allocations: 0 bytes)
398.20799999999997

```

What is your favourite approach for such structures? Should I expect the performance penalty of the first approach (`mutable struct`) to be very small most of the time?

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [May 4, 2020, 3:44pm UTC](https://discourse.julialang.org/t/mutable-struct-versus-base-refvalue/38743/2 "2020-05-04T15:44:55Z")

</div>

My worry is that 3ns could be caused by you computer doing other random things and the wrong time. You might want to run the benchmarks multiple times just to see if they are consistent or fluctuate by a small amount.

My general view is first write the code so it makes sense and is maintainable first. Then worry about improving the performance. So in that case I would go with the mutable structure. I also think in the long run it’s not going to make much different. In the first case you will probably end up with an allocation in the heap for the whole structure, in the second you end up with a (smaller) allocation for just the Float64. I it’s probably 6 of one half dozen of the other…

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [May 4, 2020, 3:47pm UTC](https://discourse.julialang.org/t/mutable-struct-versus-base-refvalue/38743/3 "2020-05-04T15:47:45Z")

</div>

The main difference should comes from whether the compiler can assume the field value never change and avoid loading them again. Since this really mainly happen when there’s non-inlined function calls that generally means that there’s something more expensive going on it should not matter much in general.

The difference **could** be significant when you use it in a loop that requires extensive compiler optimizations to vectorize. There are tricks that essentially amount to manually or helping the compiler doing [LICM](https://en.wikipedia.org/wiki/Loop-invariant_code_motion) but those are very much case dependent at that point.

---

<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:** [May 6, 2020, 4:49am UTC](https://discourse.julialang.org/t/mutable-struct-versus-base-refvalue/38743/4 "2020-05-06T04:49:11Z")

</div>

I don’t know how it performs with your use case but there’s a package for ”mutating” otherwise immutable structs.

> **[GitHub - jw3126/Setfield.jl: Update deeply nested immutable structs.](https://github.com/jw3126/Setfield.jl)**
>
> Update deeply nested immutable structs. Contribute to jw3126/Setfield.jl development by creating an account on GitHub.
