# Performance of structs with incompletely parameterized fields

**URL:** <https://discourse.julialang.org/t/performance-of-structs-with-incompletely-parameterized-fields/54580>\
**Category:** Performance\
**Tags:** parametric-types\
**Created:** [February 4, 2021, 2:05am UTC](https://discourse.julialang.org/t/performance-of-structs-with-incompletely-parameterized-fields/54580 "2021-02-04T02:05:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Deduction42](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deduction42/32/9206_2.png) [@Deduction42](https://discourse.julialang.org/u/Deduction42)\
**Post date:** [February 4, 2021, 2:05am UTC](https://discourse.julialang.org/t/performance-of-structs-with-incompletely-parameterized-fields/54580/1 "2021-02-04T02:05:34Z")

</div>

Hello,

I the performance section, it was stated that we should avoid fields with abstract types

```julia
struct MyAmbiguousStruct
   val::AbstractFloat
end

```

But what about incompletely parameterized types? How bad is something like

```julia
struct MyGenericArrayStruct{T}
   val::Array{T}
end

```

when compared to

```julia
struct MyGenericVectorStruct{T}
   val::Array{T,1}
end

```

I’m asking because it is useful for me to have structs that could have array multiple fields with different dimensions, but it becomes unwieldy to have ALL the dimension parameters show up in the parent struct. Is the performance penalty for an “incompletely parameterized type” the same as an abstract type?

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [February 4, 2021, 2:40am UTC](https://discourse.julialang.org/t/performance-of-structs-with-incompletely-parameterized-fields/54580/2 "2021-02-04T02:40:09Z")

</div>

In general, “it depends” - you could incur a lot of overhead (particularly in a hot loop), and you’d be making life harder for the compiler, but the flexibility may be worth it if runtime isn’t critical. The only way to answer the question of performance penalty for your particular application is through benchmarks, but just to give you a rough idea, compare:

```julia
julia> abstract type GenericContainer end

julia> struct MyGenericArrayStruct{T} <: GenericContainer
          val::Array{T}
       end

julia> struct MyGenericVectorStruct{T} <: GenericContainer
          val::Array{T,1}
       end

julia> total(g::GenericContainer) = sum(g.val)
total (generic function with 1 method)

```

```julia
julia> using BenchmarkTools

julia> mgas = [MyGenericArrayStruct(rand(3)) for i = 1:10^6];

julia> mgvs = [MyGenericVectorStruct(rand(3)) for i = 1:10^6];

julia> @btime mapreduce(total, +, $mgas)
  63.524 ms (1999999 allocations: 30.52 MiB)
1.5007591209103481e6

julia> @btime mapreduce(total, +, $mgvs)
  6.469 ms (0 allocations: 0 bytes)
1.499610642683319e6

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 4, 2021, 6:04am UTC](https://discourse.julialang.org/t/performance-of-structs-with-incompletely-parameterized-fields/54580/3 "2021-02-04T06:04:03Z")

</div>

You could add also the dimension as a type parameter to the wrapping type, that way you’d have both performance a d flexibility.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 4, 2021, 9:29am UTC](https://discourse.julialang.org/t/performance-of-structs-with-incompletely-parameterized-fields/54580/4 "2021-02-04T09:29:08Z")

</div>

And you can also use

> [@Deduction42](#):
>
> ```julia
> struct MyGenericVectorStruct{T}
> val::T
> end
> 
> ```

directly, if you find cumbersome to annotate `T,N` in your case. You could create an inner constructor to check the data structure if that is needed for some reason.
