# Fast alternative to mutable struct

**URL:** <https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593>\
**Category:** Performance\
**Tags:** question\
**Created:** [February 13, 2020, 5:50pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593 "2020-02-13T17:50:28Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![kaltsoplyn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kaltsoplyn/32/46634_2.png) [@kaltsoplyn](https://discourse.julialang.org/u/kaltsoplyn)\
**Post date:** [February 13, 2020, 5:50pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/1 "2020-02-13T17:50:28Z")

</div>

_ **Hi, first discourse topic/question ever, please do tell if this is the wrong place for this type of question.** _ _(I’m also new to Julia, so this might be trivial.)_

I have a function, with a couple of keyword arguments.  
(Disclaimer: I like keyword arguments to define broadly the environment/domain of my problem, and I prefer them to default arguments, because I can call and change just some of them by name).

Anyway, I thought I’d pull default values for kw args from some kind of object/structure, but also be able to change that structure at times (with a set function; a.k.a. change the “environment”), so object had to be a mutable, so I used a `mutable struct`:

```julia
mutable struct Parameters{T}
	ao::T
	bo::T
end

```

instantiated:  
`params = Parameters{Float64}(1.23, 8.77)`

defined the function:  
`f(x; a = params.ao, b = params.bo) = ...`

also defined a function to change the params:

```julia
function set(; new_ao = params.ao, new_bo = params.bo)
	params.ao = new_ao
	params.bo = new_bo
end

```

This, of course, works, but the problem is that mutable structs are apparently slow.  
If instead of a struct I use a `const array`:  
`const params = [1.23, 8.77]`

and define the function as: `f(x; a = params[1], b = params[2]) = ...`

(and also redefine the ‘`set`’ function) execution is **10x faster**!

This is a hack, though: in the new set function I’m allowed to do `params[1] = new_ao`, although the params array is `const`! But in some future version of Julia, const arrays will presumably be really immutable.

So, is there an obvious alternative I’m missing? some elegant and more future-proof way to do what I want, and still have fast execution times?

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [February 13, 2020, 5:56pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/2 "2020-02-13T17:56:57Z")

</div>

If all you are doing is passing around parameters, I’d probably put them in a NamedTuple. [https://github.com/mauro3/Parameters.jl](https://github.com/mauro3/Parameters.jl) has the `@with_kw` macro that makes it easy to use. Then just pass the NamedTuple to your functions.

---

<div class="post-metadata">

**Author:** ![tkluck](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkluck/32/15769_2.png) [@tkluck](https://discourse.julialang.org/u/tkluck)\
**Post date:** [February 13, 2020, 5:57pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/3 "2020-02-13T17:57:50Z")

</div>

> [@kaltsoplyn](#):
>
> But in some future version of Julia, const arrays will presumably be really immutable.

This is not true; `const` is not recursive. If you set `const x = [1:10]` then you are free to modify the elements of `x`; the only thing you can’t do is assign a different value to `x`.

Similarly, you should feel free to define

```julia
mutable struct Params
    something :: Float64
end

const params = Params()

```

and modify `params.something = ....` whenever you want. Is that what you are looking for?

---

<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:** [February 13, 2020, 5:59pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/4 "2020-02-13T17:59:29Z")

</div>

> [@kaltsoplyn](#):
>
> This, of course, works, but the problem is that mutable structs are apparently slow.

Why? Who told you that? Fwiw, the only reason it can be slow sometimes is because it’s mutable, since that’s the property you need, you don’t have an alternative.

> [@kaltsoplyn](#):
>
> But in some future version of Julia, const arrays will presumably be really immutable.

No that’s impossible.

---

<div class="post-metadata">

**Author:** ![kaltsoplyn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kaltsoplyn/32/46634_2.png) [@kaltsoplyn](https://discourse.julialang.org/u/kaltsoplyn)\
**Post date:** [February 13, 2020, 6:12pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/5 "2020-02-13T18:12:05Z")

</div>

@tkluck wow, that was fast, thanks!

My questions about the potential future immutability of const arrays comes from this - admittedly very old - discussion: [https://github.com/JuliaLang/julia/issues/317](https://github.com/JuliaLang/julia/issues/317)  
Reading the replies, it didn’t seem to me like the idea was completely shot down, so, yeah, that.

Now for the main part of your answer, I feel like an idiot. I was doing this late last night, and I’d swear _ **I did try** _ defining a `const` instance of the `mutable struct`, and then couldn’t set new values in the instance (with `params.ao = ...` )! I really really did it! And apparently I didn’t :(. What was I doing really?..

So, thank you, that was humbling enough for a first discourse!..

---

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [February 13, 2020, 6:27pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/6 "2020-02-13T18:27:09Z")

</div>

The difference comes because you compare setting your function parameters with a global variable `params = Parameters{Float64}(1.23, 8.77)` vs setting them with a constant `const params = [1.23, 8.77]`. If I do:

```julia
mutable struct Par{T}
	a::T
	b::T
end

const par = Par(1.23, 8.77)
f(x, a=par.a, b=par.b) = x*a/b

const arr = [1.23, 8.77]
f1(x, a=arr[1], b=arr[2]) = x*a/b

julia> using BenchmarkTools

julia> @btime f(pi)
  4.033 ns (0 allocations: 0 bytes)
0.4406110563187509

julia> @btime f1(pi)
  5.042 ns (0 allocations: 0 bytes)
0.4406110563187509

```

vs

```julia
var = Par(1.23, 8.77)
g(x, a=var.a, b=var.b) = x*a/b

varr = [1.23, 8.77]
g1(x, a=varr[1], b=varr[2]) = x*a/b

julia> @btime g(pi)
  141.142 ns (6 allocations: 96 bytes)
0.4406110563187509

julia> @btime g1(pi)
  67.992 ns (3 allocations: 48 bytes)
0.4406110563187509

```

It has nothing to do with performance of mutable structs. If you set your function parameters with a reference to a variable, the compiler needs to generate extra code.

---

<div class="post-metadata">

**Author:** ![kaltsoplyn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kaltsoplyn/32/46634_2.png) [@kaltsoplyn](https://discourse.julialang.org/u/kaltsoplyn)\
**Post date:** [February 13, 2020, 6:36pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/7 "2020-02-13T18:36:39Z")

</div>

@yuyichao as per my reply to tkluck, my reservations on const arrays are based on a [very old discussion](https://github.com/JuliaLang/julia/issues/317). I wouldn’t be surprised if real immutable arrays were pursued at some point, though; there is merit to them.

As for the performance of `mutable structs`, I was, as I of course realize now, comparing apples to oranges (a `const array` to a non-`const` struct). Still the array seems faster (I did some runs just now with `@btime`), but nowhere near 10x.

Sorry guys, I’ve been looking into Julia for maybe a week now, and in my spare time, too, so I still understand pretty much nothing! Thanks for the quick responses.

---

<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:** [February 13, 2020, 7:23pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/8 "2020-02-13T19:23:16Z")

</div>

> [@kaltsoplyn](#):
>
> @yuyichao as per my reply to tkluck, my reservations on const arrays are based on a [very old discussion](https://github.com/JuliaLang/julia/issues/317). I wouldn’t be surprised if real immutable arrays were pursued at some point, though; there is merit to them.

The point is that `const ... = [...]` will **never** make an otherwise normal array immutable. Immutable array type could be created, normal array could be made immutable, but the `const` there will play no roll in any of it.

> [@kaltsoplyn](#):
>
> Still the array seems faster

This shouldn’t be the case either…

---

<div class="post-metadata">

**Author:** ![kaltsoplyn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kaltsoplyn/32/46634_2.png) [@kaltsoplyn](https://discourse.julialang.org/u/kaltsoplyn)\
**Post date:** [February 13, 2020, 8:10pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/9 "2020-02-13T20:10:30Z")

</div>

> [@yuyichao](#):
>
> This shouldn’t be the case either…

hmm, I might have some leftover type instability. I’ll look into it later. Thanks.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [February 13, 2020, 9:58pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/10 "2020-02-13T21:58:21Z")

</div>

> [@kaltsoplyn](#):
>
> I wouldn’t be surprised if real immutable arrays were pursued at some point, though; there is merit to them.

For what it’s worth, real immutable arrays exist right now; they’re just not in the standard library:

> **[GitHub - JuliaArrays/StaticArrays.jl: Statically sized arrays for Julia](https://github.com/JuliaArrays/StaticArrays.jl)**
>
> Statically sized arrays for Julia. Contribute to JuliaArrays/StaticArrays.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 13, 2020, 10:02pm UTC](https://discourse.julialang.org/t/fast-alternative-to-mutable-struct/34593/11 "2020-02-13T22:02:50Z")

</div>

`params` is `const`, the content of `params` is not `const` – this is a well defined state of affairs in Julia. Use it as you like.

```julia
julia> const params = [1.25, 2.5]
2-element Array{Float64,1}:
 1.25
 2.5

julia> params = "abc"
ERROR: invalid redefinition of constant params
Stacktrace:
 [1] top-level scope at REPL[2]:1

julia> params[1] *= 4
5.0

julia> params
2-element Array{Float64,1}:
 5.0
 2.5

```
