@@ -739,20 +739,29 @@ extension _NativeSet {
739
739
internal __consuming func intersection(
740
740
_ other: _NativeSet < Element >
741
741
) -> _NativeSet < Element > {
742
- // Prefer to iterate over the smaller set. However, we must be careful to
743
- // only include elements from `self`, not `other`.
744
- guard self . count <= other. count else {
745
- return genericIntersection ( other)
746
- }
747
- // Rather than directly creating a new set, mark common elements in a bitset
748
- // first. This minimizes hashing, and ensures that we'll have an exact count
749
- // for the result set, preventing rehashings during insertions.
750
- return _UnsafeBitset. withTemporaryBitset ( capacity: bucketCount) { bitset in
742
+ // Rather than directly creating a new set, mark common elements in a
743
+ // bitset first. This minimizes hashing, and ensures that we'll have an
744
+ // exact count for the result set, preventing rehashings during
745
+ // insertions.
746
+ _UnsafeBitset. withTemporaryBitset ( capacity: bucketCount) { bitset in
751
747
var count = 0
752
- for bucket in hashTable {
753
- if other. find ( uncheckedElement ( at: bucket) ) . found {
754
- bitset. uncheckedInsert ( bucket. offset)
755
- count += 1
748
+ // Prefer to iterate over the smaller set. However, we must be careful to
749
+ // only include elements from `self`, not `other`.
750
+ if self . count > other. count {
751
+ for element in other {
752
+ let ( bucket, found) = find ( element)
753
+ if found {
754
+ // `other` is a `Set`, so we can assume it doesn't have duplicates.
755
+ bitset. uncheckedInsert ( bucket. offset)
756
+ count += 1
757
+ }
758
+ }
759
+ } else {
760
+ for bucket in hashTable {
761
+ if other. find ( uncheckedElement ( at: bucket) ) . found {
762
+ bitset. uncheckedInsert ( bucket. offset)
763
+ count += 1
764
+ }
756
765
}
757
766
}
758
767
return extractSubset ( using: bitset, count: count)
@@ -771,8 +780,9 @@ extension _NativeSet {
771
780
var count = 0
772
781
for element in other {
773
782
let ( bucket, found) = find ( element)
774
- if found {
775
- bitset. uncheckedInsert ( bucket. offset)
783
+ // Note: we need to be careful not to increment `count` here if the
784
+ // element is a duplicate item.
785
+ if found, bitset. uncheckedInsert ( bucket. offset) {
776
786
count += 1
777
787
}
778
788
}
0 commit comments