While it’s interesting to see how much overhead dynamic method lookup and calling has in Julia, it’s only part of the reason dynamic dispatch is slower. Another important one that’s come up multiple times in practice is the overhead from boxing and unboxing arguments and return values that would otherwise be stack-allocated. `hash(::Vector{<abstract type>}, ::UInt)` allocates quite a bit due to type instability: why can't hash(::Any) infer `UInt` return type? · Issue #44244 · JuliaLang/julia · GitHub and [WIP] dynamic dispatch optimization: avoid boxing stack-allocated inputs by NHDaly · Pull Request #50136 · JuliaLang/julia · GitHub talk about this, and there should be related discussion threads on Discourse too.
Edit: this previous thread has similar benchmark and a comparison against Rust: Curious about the internals of dynamic dispatch - #13 by HashBrown
Suffice it to say that a benchmark that captures the totality of runtime dispatch overhead should consider these other factors, regardless of whether the purpose is to compare against other languages.