-
Notifications
You must be signed in to change notification settings - Fork 40
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
Rely on the fallback definition of checkindex
#255
base: master
Are you sure you want to change the base?
Conversation
Tests pass without it, and it's a source of ambiguities with FFTViews.
Codecov Report
@@ Coverage Diff @@
## master #255 +/- ##
==========================================
- Coverage 95.41% 95.40% -0.02%
==========================================
Files 5 5
Lines 436 435 -1
==========================================
- Hits 416 415 -1
Misses 20 20
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.
This was a performance enhancement, as otherwise bounds-checking does not realize that an OffsetRange
is essentially a range, and loops over each element.
Master
julia> r = OffsetArray(1:1000);
julia> @btime checkbounds(Bool, 1:10000, $(Ref(r))[]);
3.207 ns (0 allocations: 0 bytes)
This branch
julia> @btime checkbounds(Bool, 1:10000, $(Ref(r))[]);
1.604 μs (0 allocations: 0 bytes)
Wonder what's the best way to avoid such ambiguities are, as they are bound to crop up when one package specializes on the first argument and another on the second.
Indirection/traits. We need to fix abstract type RangeStyle end
struct IsRange <: RangeStyle end
struct NotARange <: RangeStyle end
RangeStyle(::AbstractVector) = NotARange()
checkindex(::Type{Bool}, inds::AbstractUnitRange, index::AbstractVector) = _checkindex(Bool, inds, RangeStyle(index), index)
_checkindex(Bool, inds, ::IsRange, index) = checkindex(Bool, inds, first(index) & checkindex(Bool, inds, last(index))
_checkindex(Bool, inds, ::RangeStyle, index) = # the current AbstractArray fallback Then this package could specialize Would you like to add that or should I? One should carefully consider names etc: do we really want a single trait that declares "this is a range for all purposes" or a narrower one that says "all you have to do is check the endpoints"? We'll have to have a transitional plan until Julia 1.8 comes out, but let's get the right fix done first and then figure out the bandaid later. |
Could you add this to |
Sure! For when we get to the bandaid, can you give a real-world example where this performance matters? I.e., something that a normal user might actual trip across. One can of course use a |
Yes for indices that are julia> r = 1:1:100;
julia> ro = OffsetArray(r);
julia> v = ones(1000);
julia> @btime $v[$r];
237.578 ns (1 allocation: 896 bytes)
julia> @btime $v[$ro];
5.158 μs (1 allocation: 896 bytes) Interestingly even with bounds-checking disabled there's a performance hit, which might be improved. julia> f(v, r) = @inbounds v[r];
julia> @btime f($v, $r);
233.909 ns (1 allocation: 896 bytes)
julia> @btime f($v, $ro);
2.642 μs (1 allocation: 896 bytes) |
I guess we have to make a decision then:
If we go with the latter, then all the methods to index by an If we go with the former, we may have quite a lot of work to do! |
I'm in support of the trait-based approach, although I realize it's a lot of work. Suggesting an user to be conscious of types seems far from ideal. Also adding a new type would invariably lead to a lot of ambiguities. Moreover, other packages trying something similar would have to reinvent the wheel unless they study this package well. Ideally |
Tests pass without it, and it's a source of ambiguities with FFTViews.