Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

::Function argument in recursive function is expensive #18207

Closed
KristofferC opened this issue Aug 23, 2016 · 2 comments
Closed

::Function argument in recursive function is expensive #18207

KristofferC opened this issue Aug 23, 2016 · 2 comments
Labels
performance Must go faster

Comments

@KristofferC
Copy link
Member

Just having a function as an argument in a recursive function creates an allocation at each call. This is a minimized example from one of my packages:

function knn_kernel2!(index::Int)
    index > 1_000_000 && return
    knn_kernel2!(2*index)
    knn_kernel2!(2*index+1)
    return
end

function knn_kernel2!(index::Int,
                      skippoint::Function)
    index > 1_000_000 && return
    knn_kernel2!(2*index, skippoint)
    knn_kernel2!(2*index+1, skippoint)
    return
end
julia> @time knn_kernel2!(1)
  0.003125 seconds (4 allocations: 160 bytes)

julia> @time knn_kernel2!(1, x->false)
  0.181919 seconds (2.00 M allocations: 30.511 MB, 2.16% gc time)

Is there anyway to workaround this?

@KristofferC KristofferC added the performance Must go faster label Aug 23, 2016
@KristofferC
Copy link
Member Author

Hmm, I seem to already have reported this at #16185 (comment) and that was commented by @JeffBezanson with:

The reduced example in that issue might not get fixed. The extra code allows dynamic dispatch to a version of g specialized for f. The method in the example is probably not performance-critical, since all it does is call another function. This is part of the cost of faster higher-order functions.

So closing this but I don't know how to solve the problem...

@JeffBezanson
Copy link
Member

JeffBezanson commented Aug 23, 2016

A possible workaround is to force specialization like this:

function knn_kernel2!{F<:Function}(index::Int, skippoint::F)

But this is definitely a real issue, concerning the performance of dynamic dispatch and our calling convention. However fixing it is definitely a long-term project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Must go faster
Projects
None yet
Development

No branches or pull requests

2 participants