# Elimination of (unnecessary) runtime dispatch allocations

**URL:** <https://discourse.julialang.org/t/elimination-of-unnecessary-runtime-dispatch-allocations/113475>\
**Category:** Internals & Design\
**Tags:** box, allocations, runtime-dispatch\
**Created:** [April 24, 2024, 8:13pm UTC](https://discourse.julialang.org/t/elimination-of-unnecessary-runtime-dispatch-allocations/113475 "2024-04-24T20:13:32Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 24, 2024, 8:25pm UTC](https://discourse.julialang.org/t/elimination-of-unnecessary-runtime-dispatch-allocations/113475/2 "2024-04-24T20:25:17Z")

</div>

Here’s a more relevant issue:

> <https://github.com/JuliaLang/julia/issues/23210>
>
> Consider the following code:
> \`\`\`julia
> abstract type MyAbs end
> test(x::Abstrac…tVector, m::MyAbs) = test(Vector{Int}(x), m)
> 
> struct MyType1 \<: MyAbs end
> test(x::Vector{Int}, ::MyType1) = 1
> 
> struct MyType2 \<: MyAbs end
> test(x::Vector{Int}, ::MyType2) = 2
> 
> struct MyType3 \<: MyAbs end
> test(x::Vector{Int}, ::MyType3) = 3
> \`\`\`
> Here, the first definition of \`test\` defers execution to one of the next three definitions of \`test\` depending on the specific type of \`m\`.  
> 
> Now, if we call \`test\` on \`Vector{Int}\` and \`MyAbs\`, the return type is always \`Int\` and therefore stable:
> \`\`\`julia
> julia\> VERSION
> v"0.7.0-DEV.1283"
> 
> julia\> code\_warntype(test, (Vector{Int}, MyAbs))
> Variables:
> ...
> Body:
> ...
> end::Int64
> 
> Variables:
> ...
> Body:
> ...
> end::Int64
> 
> Variables:
> ...
> Body:
> ...
> end::Int64
> 
> Variables:
> ...
> Body:
> ...
> end::Int64
> \`\`\`
> However, if we define one more, 4th concrete subtype of \`MyAbs\` and corresponding \`test\` function, suddenly calling \`test\` on \`Vector{Int}\` and \`MyAbs\` returns \`Any\` and becomes unstable:
> \`\`\`julia
> julia\> struct MyType4 \<: MyAbs end
> 
> julia\> test(x::Vector{Int}, ::MyType4) = 4
> test (generic function with 5 methods)
> 
> julia\> code\_warntype(test, (Vector{Int}, MyAbs))
> Variables:
> ...
> Body:
> ...
> end::Int64
> 
> Variables:
> ...
> Body:
> ...
> end::Int64
> 
> Variables:
> ...
> Body:
> ...
> end::Int64
> 
> Variables:
> ...
> Body:
> ...
> end::Int64
> 
> Variables:
> ...
> Body:
> ...
> end::Any
> \`\`\`
> Note the last return type is \`Any\`.
> 
> This is very strange. Is 4 some kind of an intentional threshold?
> 
> This is a problem when, for example, I define an array of \`MyAbs\` containing instances of \`MyType1\`, ..., \`MyType4\` and iterate over it by a for loop to execute \`test\` on each element of the array. The output of \`test\` is not type-stable.
> 
> The problem is reproducible in Julia 0.6 as well.

In short, there’s a tradeoff. These are _method table optimizations_ — they’re dependent upon the state of the method table. And thus, when you add more methods, you end up with _method table invalidations_. Generally when you have lots of methods, there will probably be more defined.

So, yes, you can increase `max_methods` and rebuild Julia if you want. But you’ll pay for it in other places — namely, higher compilation times and more invalidations.

---

_[View the full topic](https://discourse.julialang.org/t/elimination-of-unnecessary-runtime-dispatch-allocations/113475)._
