How to Bypass the World Age Problem

Before now I was on Julia v0.5. The problem did not exist, so I don’t understand what you mean by this statement. The reality is that I cannot use it because my code will be become so slow that it will be useless.

To be specific, if I translate the GIST linked above to v0.5 (basically just remove invokelatest in the last benchmark) then the runtime matches that of the reference.

The problem didn’t exist because the invokelastest was implicit and unpredictable.

I’ll repeat that invokelastest will never add overhead that’s not present with dynamic dispatch on 0.5 and the reason you can call that function on 0.5 at all is due to dynamic dispatch. If you do see a large overhead, you are not using it correctly.

I get that there is something I am not doing correctly. This is exactly what I am trying to find out in this thread. How do I fix the performance in the following code? (this is more involved than the first example, because it is much closer to my actual use case)

using BenchmarkTools
using Calculus: differentiate
function Base.diff(ex::Expr)
   ex_d = differentiate(ex, :r)
   return eval( :( (r->$ex, r->$ex_d)) )
end
type AnalyticPotential{F0,F1}
   f::F0
   f_d::F1
end
function innertest(p::AnalyticPotential, N)
   s0 = 0.0
   s1 = 0.0
   for n = 1:N
      x = rand()
      s0 += p.f(x)
      s1 += p.f_d(x)
   end
end
Nruns = 1_000_000
a = 1.234
r0 = 0.9
function test(N)
   f, df = diff(:( exp(- $(a/r0) * r + $a) ) )
   p = AnalyticPotential( r->Base.invokelatest(f, r), r -> Base.invokelatest(df, r) )
   innertest(p, 10)
   @btime innertest($p, $N)
end
test(Nruns)

Base.invokelatest(AnalyticPotential, f, df)

Actually no, I didn’t realize the later ones is where you need it so

    Base.invokelatest(innertest, p, 10)
    @btime Base.invokelatest(innertest, $p, $N)

Well, that was embarrassingly easy. Somehow, this didn’t occur to me at all. Thank you for your patience.

So I should understand invokelatest as “please use dynamic dispatch for this call”?

would it be feasible to create a macro that applies this to an entire block of code?

Yes.

It should be pretty easy to do…

FWIW inreimplemenred the functionality using macros and it works equally well if not better and invokelatest is ninlinger needed. Thank you for making that point.

3 Likes

Not exactly. Julia always uses dynamic dispatch when calling methods. But which “world” – i.e. global snapshot of available methods – is determined statically although the method within that world is chosen dynamically. So what invokelatest does is to choose a world dynamically rather than statically, using the latest world.

1 Like

Thank you for clarifying. It is a bit strange initially but one probably gets used to it over time.