Dangers of abusing multiple dispatch: missing optimization?

I was reading this section in the manual https://docs.julialang.org/en/stable/manual/performance-tips/#the-dangers-of-abusing-multiple-dispatch-aka-more-on-types-with-values-as-parameters , and I realized I’ve done this in some cases, as it is very convenient. I construct an instance of a type for dispatch purposes, but which type depends on some condition. Here’s two test examples

using BenchmarkTools
immutable Type1 end
immutable Type2 end
f(x, ::Type1) = 3.*x
f(x, ::Type2) = 5.*x
function test1(N)
  for i = 1:N
    r = rand()
    if r > .5
      a = Type1()
    else
      a = Type2()
    end
    f(r, a)
  end
end
function test2(N)
  for i = 1:N
    r = rand()
    if r > .5
      a = Type1()
      f(r, a)
    else
      a = Type2()
      f(r, a)
    end
  end
end
@benchmark test1(1000)
median time:      18.571 μs (0.00% GC)
@benchmark test2(1000)
  median time:      1.967 μs (0.00% GC)

test1 is similar to what I’ve done in the past. I realized here that test2 substantially faster. It appears that within the if block there is no type instability, so the dispatch is easy.

I wonder if some future optimization can make performance the same?

yes. That optimization is known as “jump-threading” is pretty standard – although not yet implemented in Julia, it’s perhaps just waiting for someone to decide to dive into it :slight_smile:.

1 Like