JuliaGizmos / Observables.jl

observable refs
Other
105 stars 32 forks source link

Always use invokelatest #65

Closed timholy closed 3 years ago

timholy commented 3 years ago

map was not safe in conjunction with @async. Since even one of the examples in the manual used it that way, let's just get rid of the special dispatch for InternalFunction.

Fixes #50

@SimonDanisch, I know this one might have made you sad. Is there a place where this matters more than others?

Benchmarks:

julia> f1(x) = sin(x)
f1 (generic function with 1 method)

julia> f2(x) = Base.invokelatest(sin, x)
f2 (generic function with 1 method)

julia> using BenchmarkTools

julia> @btime f1(x) setup=(x=rand());
  3.681 ns (0 allocations: 0 bytes)

julia> @btime f2(x) setup=(x=rand());
  55.407 ns (3 allocations: 48 bytes)

julia> f3(x) = sin(x[])
f3 (generic function with 1 method)

julia> @btime f3(x) setup=(x=Ref{Any}(rand()));
  18.016 ns (1 allocation: 16 bytes)

So it's about 3x the cost of a single runtime dispatch (which due to poor inferrability, Makie has a lot of).

SimonDanisch commented 3 years ago

Well, if it crashes I guess we need to get rid of it in any case ;) Maybe we can bring back something like this for code where it matters with FunctionWrappers or so!