# Arrays of structs/tuples with mutable members

**URL:** <https://discourse.julialang.org/t/arrays-of-structs-tuples-with-mutable-members/45754>\
**Category:** Performance\
**Created:** [August 29, 2020, 4:56pm UTC](https://discourse.julialang.org/t/arrays-of-structs-tuples-with-mutable-members/45754 "2020-08-29T16:56:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [August 29, 2020, 4:56pm UTC](https://discourse.julialang.org/t/arrays-of-structs-tuples-with-mutable-members/45754/1 "2020-08-29T16:56:42Z")

</div>

I tested the performance of an array of tuples and structs in Julia 1.3.1 and 1.5.1 and am a bit confused about the results. There are eight separate times based on three choices: 1.3.1 vs 1.5.1, structs vs tuples, and mutable member vs no mutable members.

Briefly: 1.5.1 is much faster than 1.3.1 in the case of a mutable member for both structs and tuples. The timing results and code are below.

I have a question about this: For the 1.5.1 execution, the timing results imply that structs and tuples are not heap-allocated even when they contain a mutable member. How does the run-time system keep track of whether the underlying array [72., 31.] has any live pointers to it (for garbage collection)? Is there any “gotcha” in using this new feature?

```julia
julia> include("testtup1.jl")
WARNING: replacing module testtup1.
VERSION = 1.3.1
Test of tuple with mutable member
  0.203990 seconds (25.00 M allocations: 762.940 MiB, 12.14% gc time)
Test of struct with mutable member
  0.200921 seconds (25.00 M allocations: 762.940 MiB, 9.90% gc time)
Test of tuple with all immutable members
  0.065874 seconds (7 allocations: 416 bytes)
Test of struct with all immutable members
  0.048031 seconds (7 allocations: 416 bytes)
Main.testtup1

```

```julia
julia> include("testtup1.jl")
WARNING: replacing module testtup1.
VERSION = 1.5.1
Test of tuple with mutable member
  0.058091 seconds (2 allocations: 176 bytes)
Test of struct with mutable member
  0.056815 seconds (2 allocations: 176 bytes)
Test of tuple with all immutable members
  0.060029 seconds (2 allocations: 208 bytes)
Test of struct with all immutable members
  0.048437 seconds (2 allocations: 208 bytes)
Main.testtup1

```

```julia
module testtup1

struct Example{T}
    a::T
    b::Int
end

function multiple_push_pop_tup(u)
    T = Tuple{typeof(u), Int}
    x = Vector{T}()
    resize!(x,5)
    sum1 = 0.0
    for k = 1 : 5_000_000
        k1 = (k % 2) + 1
        for i = 1 : 5
            x[i]= (u,k1)
        end
        for i = 1 : 5
            v = x[i]
            sum1 += v[1][v[2]]
        end
    end
    return x[2], sum1
end

function multiple_push_pop_struct(u)
    T = Example{typeof(u)}
    x = Vector{T}()
    resize!(x,5)
    sum1 = 0.0
    for k = 1 : 5_000_000
        k1 = (k % 2) + 1
        for i = 1 : 5
            x[i]= T(u,k1)
        end
        for i = 1 : 5
            v = x[i]
            sum1 += v.a[v.b]
        end
    end
    return x[2], sum1
end

const w = [72., 31.]
multiple_push_pop_tup(w)
multiple_push_pop_struct(w)
const y = (72., 31.)
multiple_push_pop_tup(y)
multiple_push_pop_struct(y)

println("VERSION = ", VERSION)
println("Test of tuple with mutable member")
@time multiple_push_pop_tup(w)
println("Test of struct with mutable member")
@time multiple_push_pop_struct(w)
println("Test of tuple with all immutable members")
@time multiple_push_pop_tup(y)
println("Test of struct with all immutable members")
@time multiple_push_pop_struct(y)
end

```

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [August 29, 2020, 5:10pm UTC](https://discourse.julialang.org/t/arrays-of-structs-tuples-with-mutable-members/45754/2 "2020-08-29T17:10:19Z")

</div>

(Sorry about my initial post in which the timing was done incorrectly; I think I have revised it now correctly.)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 29, 2020, 6:57pm UTC](https://discourse.julialang.org/t/arrays-of-structs-tuples-with-mutable-members/45754/3 "2020-08-29T18:57:25Z")

</div>

> [@Stephen\_Vavasis](#):
>
> Is there any “gotcha” in using this new feature?

No. Garbage collection on the mutable members works normally, no different than for an array of those members — the gc still knows it has a pointer to the members in the array data.

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [August 29, 2020, 7:06pm UTC](https://discourse.julialang.org/t/arrays-of-structs-tuples-with-mutable-members/45754/4 "2020-08-29T19:06:41Z")

</div>

Thank you very much for the prompt response, Steven. In the documentation for sorted containers here: [Sorted Containers · DataStructures.jl](https://juliacollections.github.io/DataStructures.jl/latest/sorted_containers/#Tokens-for-Sorted-Containers-1), there is a discussion in the fourth paragraph about performance of tokens and semitokens. It seems like this section of the documentation needs to be scrapped? Maybe semitokens themselves should be discarded?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 29, 2020, 7:23pm UTC](https://discourse.julialang.org/t/arrays-of-structs-tuples-with-mutable-members/45754/5 "2020-08-29T19:23:11Z")

</div>

> [@Stephen\_Vavasis](#):
>
> It seems like this section of the documentation needs to be scrapped? Maybe semitokens themselves should be discarded?

Yes, it sounds like that’s only applicable to Julia \< 1.5.
