# Penalty for not defining mutable struct fields types

**URL:** <https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020>\
**Category:** Performance\
**Created:** [October 16, 2023, 2:45pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020 "2023-10-16T14:45:22Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jondavis847](https://avatars.discourse-cdn.com/v4/letter/j/da6949/32.png) [@jondavis847](https://discourse.julialang.org/u/jondavis847)\
**Post date:** [October 16, 2023, 2:45pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/1 "2023-10-16T14:45:22Z")

</div>

Hello,

I have a rather large and complicated mutable struct which I use to just house pre-allocated Vector{SArray} 's of a system. I can then pass this struct to my functions which get called many times without allocating which is great!

The size of those matrices and vectors are dependent on the inputs to the system. I have been using type parameters to specify size where possible i.e.

```julia
q::Vector{SArray{S,T,1} where S<:Tuple}

```

but the system is rather complicated (~100 fields), so the struct definition is rather messy, and I’ve spent a few hours now tracking down method errors. This got me thinking, do I even need to do this? If I just don’t define the type of the field, my struct constructor will output exactly the right type, and then just operate on that fully defined struct. Once the constructor creates the mutable struct container, the size and type of the fields never changes for that system or its functions.

I think I may still want to define the field types just for user input verification, but is there any performance reason to define it? Could type instability still be an issue, even if the mutable struct is fully defined at construction automatically?

Thanks.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [October 16, 2023, 3:42pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/2 "2023-10-16T15:42:33Z")

</div>

[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)

Perhaps construct an instance of your struct without declaring field types and then inspect it like this:

```julia
for name in fieldnames(S)
  @show name typeof(getfield(s,name))
end

```

Then define your struct type with those field types.

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [October 16, 2023, 6:08pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/3 "2023-10-16T18:08:26Z")

</div>

Typically a function barrier around the performance sensitive loops solves that kind of problem (assuming each loop uses only a reasonable subset of the 100+ struct fields). Something along the lines of

```julia
mutable struct Foo
  x
  y
  z
end

function f(a)
   	# Run time dispatch
	loop1(a.x, a.y, a.z)
end

function loop1(x, y, z)
  for x1 in x
  	# etc - static dispatch
  end
end

a = Foo([1,2], [2.0, 3.0], [4,5])
f(a)

```

Doesn’t that approach work for your problem?

---

<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:** [October 16, 2023, 6:19pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/4 "2023-10-16T18:19:28Z")

</div>

I seem to remember there was a small package with a macro that automatically adds type parameters to a struct, but I can’t find it. Anyone know what I’m talking about?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 16, 2023, 6:31pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/5 "2023-10-16T18:31:15Z")

</div>

> [@jondavis847](#):
>
> `q::Vector{SArray{S,T,1} where S<:Tuple}`

I’m not quite sure about this signature. Is it supposed to represent many different dimensionalities? Putting the `where` clause on the field inside the struct means the field will not be concrete I think.

Can’t you do

```julia
MyType{T}
    q::Vector{T}
end

```

for example?

---

<div class="post-metadata">

**Author:** ![jondavis847](https://avatars.discourse-cdn.com/v4/letter/j/da6949/32.png) [@jondavis847](https://discourse.julialang.org/u/jondavis847)\
**Post date:** [October 16, 2023, 7:25pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/6 "2023-10-16T19:25:16Z")

</div>

Thanks for the reference. Sounds like I definitely want to specify the field types using what seems like could be any of the techniques listed in the thread so far. I was doing something similar to your recommendation albeit more manually by just creating the structures, typeof() on the field, and setting it to that.

---

<div class="post-metadata">

**Author:** ![jondavis847](https://avatars.discourse-cdn.com/v4/letter/j/da6949/32.png) [@jondavis847](https://discourse.julialang.org/u/jondavis847)\
**Post date:** [October 16, 2023, 7:28pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/7 "2023-10-16T19:28:39Z")

</div>

This is very interesting. You’re correct that I have many functions that have a subset of the fields as arguments. Actually, I already have a wrapper Foo that I feed the whole struct to, and then a dispatched method Foo that gets fed all of the arguments it needs that I was using to initialize the structs. I’m definitely going to keep this technique in mind but it might be that I’m already accidentally doing this.

---

<div class="post-metadata">

**Author:** ![jondavis847](https://avatars.discourse-cdn.com/v4/letter/j/da6949/32.png) [@jondavis847](https://discourse.julialang.org/u/jondavis847)\
**Post date:** [October 16, 2023, 7:31pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/8 "2023-10-16T19:31:34Z")

</div>

> **[GitHub - jonniedie/ConcreteStructs.jl: 🏩🏠🌆🏨🌇🏦](https://github.com/jonniedie/ConcreteStructs.jl)**
>
> 🏩🏠🌆🏨🌇🏦. Contribute to jonniedie/ConcreteStructs.jl development by creating an account on GitHub.

Actually JonnieDie is a good friend of mine and he recommended this to me a long time ago for something else. This might a really good use case for it, though I’m very grateful for the other recommendations in the thread to help with my Julia education!

---

<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:** [October 16, 2023, 7:35pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/9 "2023-10-16T19:35:15Z")

</div>

As the dev behind this and ComponentArrays, JonnieDie has become a good friend to lots of people ^^

---

<div class="post-metadata">

**Author:** ![jondavis847](https://avatars.discourse-cdn.com/v4/letter/j/da6949/32.png) [@jondavis847](https://discourse.julialang.org/u/jondavis847)\
**Post date:** [October 16, 2023, 7:37pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/10 "2023-10-16T19:37:40Z")

</div>

For my specific case, T just ends up being AbstractFloat so I can switch bit sizes, which I do utilize. In my example with q, q is a vector of SVectors, but the SVector elements can be arbitrary sizes for a given system config. It just depends on the inputs what the size of each element will be. I have other fields that will be Vectors of Matrices, or even Vectors of other MyTypes.

There are other ways for me to define those structures technically but I can stay very close to the textbook notation by writing it this way, which I think is very cool that Julia can do!

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 16, 2023, 8:20pm UTC](https://discourse.julialang.org/t/penalty-for-not-defining-mutable-struct-fields-types/105020/11 "2023-10-16T20:20:01Z")

</div>

> [@jondavis847](#):
>
> For my specific case, T just ends up being AbstractFloat

What I actually meant was that `T` could represent your entire `SArray{...}`. If `T` specifically is currently used for a number type, replace the parameter name with `S` or `R` or any other name.
