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)
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.
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.