-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add intersect(::AbstractRange, ::AbstractVector)
#41769
Add intersect(::AbstractRange, ::AbstractVector)
#41769
Conversation
@IanButterworth Cannot refer to |
Moving to function intersect(vec::AbstractVector, r::AbstractRange)
common = Iterators.filter(x -> x ∈ r, vec)
seen = Set{eltype(vec)}(common)
return vectorfilter(_shrink_filter!(seen), common)
end
intersect(r::AbstractRange, vec::AbstractVector) = intersect(vec, r) |
b865814
to
0d20b06
Compare
Done. Thanks! |
Just copying the benchmarks over from #41759
|
We don't currently define an explicit method for |
Something interesting is that this could be about 2x faster if we used a Set implimentation closer to the one in Dictionaries.jl's. specifically of you use the version of a set that uses insertion order, this could just return the elements of the set as a list without an extra allocation. |
@simeonschaub I don’t immediately see what would be the approach. Should it be just a fall-back method with a naive implementation? Like looping through the shorter range and checking if each element is in the longer range? Also, what ambiguities can occur now that could not occur before this method?
@oscardssmith Thanks for the suggestion. Is there a set implementation which guarantees the insertion order in Julia? I could not find it. Or do you propose to write it first (maybe based on the mentioned Dictionaries.jl package)? |
Yes, seems reasonable.
No, not currently. That would be a much bigger project, so I wouldn't bother for now. |
0d20b06
to
8c2c523
Compare
Rebased and added |
8c2c523
to
b1db906
Compare
There's still one more error but I am not sure it's related. |
@simeonschaub @oscardssmith is this RTM? |
No objections here. |
Some return type comparison and benchmarks vs. master using BenchmarkTools
for a in [1:4, 1:1.0:4, 10:4:30, collect(1:4)]
for b in [2:4, 2:1.0:4, 14:4:30, collect(2:6)]
r = Base.intersect(a, b)
print(a, "\t", b, "\t", typeof(r),"\t", r, "\t")
@btime Base.intersect($a, $b)
end
end
I didn't expect this PR to speed this up so much!
|
Is it acceptable that the return type has changed in some of the examples above? |
Imo, yes, but I'll put a triage label on it for good measure. |
Yes would be worth triaging, currently returning something of the same |
IMO I think it's ok as it's the type promotion of the eltype of the two args, which makes sense, and that could just be marked with a |
Just a note: the return type has changed for the
Someone might dislike this inconsistency (promotion & no promotion) between the |
From triage: 👍 this is good. We think all the methods (of intersect and union) should be consistent with return type, so they should all promote. |
Ping for review & merge @oscardssmith @simeonschaub @rfourquet |
Needs a rebase and a squash of all commits :) |
b95c68e
to
59a7817
Compare
Also adds: - `intersect(::AbstractRange, ::AbstractRange)` - `intersect(::AbstractRange, ::AbstractRange)` Closes JuliaLang#41759 Co-authored-by: Ian Butterworth <i.r.butterworth@gmail.com> Co-authored-by: Jeff Bezanson <jeff.bezanson@gmail.com>
The FreeBSD failure appears unrelated |
Thank you all for your help. |
No, thank you @barucden! 👍🙂 |
Seems like this might have destroyed performance of Would you be willing to look into that? |
If my understanding is correct, you propose to make a special method Wouldn't it, however, violate the decision
from triage? |
Seems like this needs some more triage given #41769 (comment) |
intersect(s::AbstractSet, itr, itrs...) = intersect!(intersect(s, itr), itrs...) | ||
function intersect(s::AbstractSet, itr, itrs...) | ||
T = promote_eltype(s, itr, itrs...) | ||
return intersect!(Set{T}(s), itr, itrs...) |
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 is a bug --- it means we give a different container type for 3 arguments than 2 (and a different type than 1.7).
On 1.7:
julia> intersect(BitSet([1,2]), [1,2], [2])
BitSet with 1 element:
2
julia> intersect(BitSet([1,2]), [1,2])
BitSet with 2 elements:
1
2
on master:
julia> intersect(BitSet([1,2]), [1,2], [2])
Set{Int64} with 1 element:
2
julia> intersect(BitSet([1,2]), [1,2])
BitSet with 2 elements:
1
2
A bug was introduced for 3 arguments version of `intersect` in JuliaLang#41769. The container type always changed to `Set`: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) Set{Int64} with 1 element: 2 ``` This is an attempt to return to the original behavior: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) BitSet with 1 element: 2 ```
A bug was introduced for 3 arguments version of `intersect` in JuliaLang#41769. The container type always changed to `Set`: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) Set{Int64} with 1 element: 2 ``` This is an attempt to return to the original behavior: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) BitSet with 1 element: 2 ```
A bug was introduced for 3 arguments version of `intersect` in JuliaLang#41769. The container type always changed to `Set`: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) Set{Int64} with 1 element: 2 ``` This is an attempt to return to the original behavior: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) BitSet with 1 element: 2 ```
A bug was introduced for 3 arguments version of `intersect` in #41769. The container type always changed to `Set`: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) Set{Int64} with 1 element: 2 ``` This is an attempt to return to the original behavior: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) BitSet with 1 element: 2 ```
A bug was introduced for 3 arguments version of `intersect` in JuliaLang#41769. The container type always changed to `Set`: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) Set{Int64} with 1 element: 2 ``` This is an attempt to return to the original behavior: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) BitSet with 1 element: 2 ```
A bug was introduced for 3 arguments version of `intersect` in JuliaLang#41769. The container type always changed to `Set`: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) Set{Int64} with 1 element: 2 ``` This is an attempt to return to the original behavior: ``` julia> intersect(BitSet([1,2]), [1,2], [2]) BitSet with 1 element: 2 ```
Closes #41759