@@ -739,20 +739,29 @@ extension _NativeSet {
739739 internal __consuming func intersection(
740740 _ other: _NativeSet < Element >
741741 ) -> _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
751747 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+ }
756765 }
757766 }
758767 return extractSubset ( using: bitset, count: count)
@@ -771,8 +780,9 @@ extension _NativeSet {
771780 var count = 0
772781 for element in other {
773782 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) {
776786 count += 1
777787 }
778788 }
0 commit comments