-
Notifications
You must be signed in to change notification settings - Fork 66
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
Fix breakage from the new ReinterpretArray
#60
Conversation
Codecov Report
@@ Coverage Diff @@
## master #60 +/- ##
=======================================
Coverage 93.89% 93.89%
=======================================
Files 14 14
Lines 508 508
=======================================
Hits 477 477
Misses 31 31
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. I have thought about the Reinterpret stuff for a while but haven't fixed it yet. I will need to do some benchmarks here to see if it is perhaps worth just doing a copy to a new array instead of reinterpreting.
src/ball_tree.jl
Outdated
@@ -4,7 +4,7 @@ | |||
# The tree uses the triangle inequality to prune the search space | |||
# when finding the neighbors to a point, | |||
struct BallTree{V <: AbstractVector,N,T,M <: Metric} <: NNTree{V,M} | |||
data::Vector{V} | |||
data::AbstractVector{V} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be bad for performance because this is an abstract field. See (https://docs.julialang.org/en/stable/manual/performance-tips/#Avoid-containers-with-abstract-type-parameters-1),
Perhaps we need to just do like
BallTree{V <: AbstractVector, ...}
data::V
.
.
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, this was a mistake on my part. I intended to leave data::Vector{V}
there, like in BruteTree
. In the latter it was necessary to do a convert
in the BruteTree
constructor, but not with BallTree
I think.
Ok! But I would have thought that copying to a new array would always be slower, no? Or perhaps there is a substantial overhead with the lazy |
Yes, indeed, the question is if there is any overhead with the lazy wrapper. Only benchmarking can tell :) |
I just did some quick tests and there is indeed a rather alarming overhead with this PR.
julia v0.6.1 + NearestNeighbors.jl (master)
julia v0.7 master + NearestNeighbors.jl (this PR)
I also created another branch ("no-reinterpret") on my fork in which all
Using this I can once more run on julia master, with similar (although a little slower) timings julia v0.7 master + NearestNeighbors.jl ("no-reinterpret" branch)
So you were right! Which makes me wonder, if I this PR follows the expected usage of the 'ReinterpretArray' wrapper, and the overhead is real, how can we get the old Also, should I open a PR with the "no-reinterpret" branch? |
We need a function barrier there. So the dynamic dispatch on |
By "there", you mean in the julia v0.7 master + NearestNeighbors.jl ("no-reinterpret" branch)
However, I'd like to understand why the |
I think we just gotta resort to copying... |
That would be too bad! I have posted a question in discourse, to try to understand if the performance problem can be overcome somehow... |
I'm closing this in favor of #61. Perhaps in the future, when/if In such case, it might be good to keep the |
Perhaps we can resurrect this. I think new optimizations for reinterpret got merged into master. |
Fix for issue #59 (see details there)