# Dramatic performance change by adding additional unused method

**URL:** <https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771>\
**Category:** Performance\
**Created:** [November 19, 2021, 11:56am UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771 "2021-11-19T11:56:03Z")\
**Posts on this page:** 14\
**Page:** 2

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [November 19, 2021, 3:35pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/21 "2021-11-19T15:35:37Z")

</div>

BTW, [this thread](https://discourse.julialang.org/t/union-splitting-vs-c/61772) might be relevant.

---

<div class="post-metadata">

**Author:** ![peremato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peremato/32/29128_2.png) [@peremato](https://discourse.julialang.org/u/peremato)\
**Post date:** [November 19, 2021, 4:08pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/22 "2021-11-19T16:08:56Z")

</div>

I tried with having a Vector of abstract types. Like this:

```julia
abstract type AbstractPlacement{T<:AbstractFloat} end

#---Volume-------------------------------------------------------------------------
struct Volume{T<:AbstractFloat, S<:AbstractShape{T}, M<:AbstractMaterial}
    label::String
    shape::S # Reference to the actual shape
    material::M # Reference to material
    daughters::Vector{AbstractPlacement{T}}
end

#---PlacedVolume-------------------------------------------------------------------
struct PlacedVolume{T<:AbstractFloat,S<:AbstractShape{T}, M<:AbstractMaterial} <: AbstractPlacement{T}
    transformation::Transformation3D{T}
    volume::Volume{T,S,M}
end

Volume{T}(label::String, shape::S, material::M) where {T,S,M} = Volume{T,S,M}(label, shape, material, Vector{AbstractPlacement{T}}())

```

The performance is twice worst than what I had originally.

---

<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:** [November 19, 2021, 4:50pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/23 "2021-11-19T16:50:28Z")

</div>

> [@peremato](#):
>
> Clearly I cannot express in a constructor all these complexity.

Are you sure you’re not trying to express too much? Most of the time the compiler can figure out the types. Can’t you just use a type parameter, and leave it to the compiler to find out what it is? Both a homogeneous and a heterogeneous vector can be expressed as `Vector{T}` for some `T`.

---

<div class="post-metadata">

**Author:** ![peremato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peremato/32/29128_2.png) [@peremato](https://discourse.julialang.org/u/peremato)\
**Post date:** [November 22, 2021, 4:14pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/24 "2021-11-22T16:14:42Z")

</div>

Sorry, perhaps I am not expressing myself well. In the system I developing I would be ending with about 20 different ‘shapes’ with more of less deep hierarchies. As I said, I can either have a unique `Volume` that encapsulates a polymorphic shape and then have a homogenous vector of all the daughter volumes (this was the original design). Or, have a different `Volume` type for each shape and have an heterogenous vector of daughters. I do not see how I can completely avoid polymorphism.

---

<div class="post-metadata">

**Author:** ![peremato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peremato/32/29128_2.png) [@peremato](https://discourse.julialang.org/u/peremato)\
**Post date:** [November 22, 2021, 4:17pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/25 "2021-11-22T16:17:52Z")

</div>

> [@fredrikekre](#):
>
> ```julia
> function OptimizationParams(;
> inlining::Bool = inlining_enabled(),
> inline_cost_threshold::Int = 100,
> inline_nonleaf_penalty::Int = 1000,
> inline_tupleret_bonus::Int = 250,
> inline_error_path_cost::Int = 20,
> max_methods::Int = 3,
> tuple_splat::Int = 32,
> union_splitting::Int = 4,
> )
> 
> ```

How heavy would be to change the `max_methods` from 3 to something like 20?

---

<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:** [November 22, 2021, 4:31pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/26 "2021-11-22T16:31:16Z")

</div>

> [@peremato](#):
>
> I do not see how I can completely avoid polymorphism.

What I’m saying is that with this type specification

> [@peremato](#):
>
> `daughters::Vector{AbstractPlacement{T}}`

it is impossible to get the benefits when the vector genuinely _is_ homogeneous. You are forcing the element type to _always_ be abstract, even when it’s not necessary. If you instead use

```julia
daughters::Vector{T} # with T<: AbstractPlacement 

```

you allow a concrete eltype when possible, and an abstract type when necessary.

---

<div class="post-metadata">

**Author:** ![peremato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peremato/32/29128_2.png) [@peremato](https://discourse.julialang.org/u/peremato)\
**Post date:** [November 22, 2021, 5:14pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/27 "2021-11-22T17:14:44Z")

</div>

> [@DNF](#):
>
> ```julia
> daughters::Vector{T} # with T<: AbstractPlacement 
> 
> ```
> 
> you allow a concrete eltype when possible, and an abstract type when necessary.

yes, but each eltype is different in general. A ‘mother’ volume may have ‘boxes’, ‘tubes’, ‘spheres’, etc. as daughters.

---

<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:** [November 22, 2021, 6:01pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/28 "2021-11-22T18:01:49Z")

</div>

Should work anyway. What am I missing?

`Vector{T}` is a vector of ‘anything’, including arbitrarily nested types, type unions, or abstract types.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [November 23, 2021, 11:57am UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/29 "2021-11-23T11:57:03Z")

</div>

Is this the [typocalypse](https://discourse.julialang.org/t/update-on-latency-and-the-typocalypse/41753)?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 23, 2021, 1:33pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/30 "2021-11-23T13:33:04Z")

</div>

For this kind of low-level polymorphism I would suggest moving the typing from the Julia type system to your own data. In other words, I suggest you create a single type that has as many `Float64` “point” fields as you may need for your largest shape, and a single `tag` field which the type is an `@enum` of your 20 primitive shapes. Then write a single `area` function that has a long `if ...; ...; elseif ...; ...; end` that deals with your 20 possible cases. This is not easily extensible by third parties but will give you some idea of how fast your system could possible be.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [November 23, 2021, 1:54pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/31 "2021-11-23T13:54:23Z")

</div>

[Unityper](https://github.com/YingboMa/Unityper.jl), which I linked to before, tries to provide a more convenient API for this, and tries to compactify the final struct in the case where not all their fields are the same.

But you can also do it manually.  
I would strongly recommend something like this approach.

---

<div class="post-metadata">

**Author:** ![peremato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peremato/32/29128_2.png) [@peremato](https://discourse.julialang.org/u/peremato)\
**Post date:** [November 23, 2021, 4:52pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/32 "2021-11-23T16:52:11Z")

</div>

Sorry if I am very slow to understand. I see that Vector{T} can be a vector of anything. But what I need is a vector that the elements are of different types all of them inheriting from some Abstract type.  
In languages such as C++ this will be implemented with an abstract class (with pure visual methods). I start understanding that the Abstract type in Julia is not equivalent (as it is not used to define an API) and is only used as a pre-condition for argument checking.

---

<div class="post-metadata">

**Author:** ![peremato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peremato/32/29128_2.png) [@peremato](https://discourse.julialang.org/u/peremato)\
**Post date:** [November 23, 2021, 5:10pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/33 "2021-11-23T17:10:46Z")

</div>

Thanks. But honestly I was thinking that Julia would provide better help for this. This is equivalent of C or even lower, since there is no switch statement in Julia.  
I was expecting that multi-dispatch would help me. I do have a reference to a `AbstractShape` and the proper method is called for each of the shapes. What I cannot understand is why the compiler cannot infer what are return values, even if I specify them in the signature of the function. The other thing I do not understand is why there is memory allocation involved in the dispatching.

---

<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:** [November 23, 2021, 5:21pm UTC](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771/34 "2021-11-23T17:21:22Z")

</div>

> [@peremato](#):
>
> But what I need is a vector that the elements are of different types all of them inheriting from some Abstract type.

Yes, and `Vector{T}` can express that. My point is that parameterizing like that leaves room _either_ for a totally heterogeneous vector _or_ for a homogeneous vector of concrete eltype.

[Previous page](https://discourse.julialang.org/t/dramatic-performance-change-by-adding-additional-unused-method/71771.md?page=1)
