Performance of (a::AbstractType)(args...) function declarations

I just finished refactoring my code to replace a lot of function calls of the form f(a::AbstractType, args…) with (a::AbstractType)(args…) since I can do that in 1.3, and it works out to slightly cleaner code. However, on testing I’m finding that the runtime has taken a massive hit, on the order of 1000x. Now, there were little things that I also fixed during this refactor, so the performance hit could be because of one of them, but before I go in and un-refactor and test all the various little things, I wanted to check if there’s any reason to expect that this primary, major change I made (defining calls on abstract types) would lead to a performance hit.

Preliminary profiling doesn’t show any glaring type instabilities.

Why don’t you try it on a minimal example? I don’t find any difference, so maybe your issue is unrelated to (a::AbstractType)(args…) .

julia> abstract type A end; struct B <: A end; b = B(); using BenchmarkTools; (::A)(x) = x * rand(); @btime b(2);
  22.957 ns (1 allocation: 16 bytes)
julia> abstract type A end; struct B <: A end; b = B(); using BenchmarkTools; (::B)(x) = x * rand(); @btime b(2);
  22.846 ns (1 allocation: 16 bytes)

Or perhaps I misunderstood what you meant?

4 Likes

That’s a good point; I should have done that.

In any case that answers my question!

1 Like

Are you literally using splatting? I think that can be quite bad for performance.

2 Likes