Skip to content

Commit e25e6bb

Browse files
committed
Auto merge of #531 - ToMe25:optimize_is_disjoint, r=Amanieu
Optimize Set is_disjoint By using the `Intersection` iterator in `HashSet::is_Disjoint` its performance can be significantly improved in some cases. This is because `intersection()` always uses the shorter set as its iterator. It would also be possible to replicate this "Iterate over the smaller set and check in the larger set" logic in the is_disjoint method. However in my benchmarks the approach I chose is faster than that. This change only causes a significant improvement when called on the larger of two disjoint sets. My benchmark results: Name | Before | After | Diff (%) -- | -- | -- | -- disjoint_is_disjoint_large_small | 1,147.43 | 535.25 | -53,35 % disjoint_is_disjoint_small_large | 535.66 | 527.59 | -1,51 % subset_is_disjoint | 9.90 | 10.44 | 5,45 % superset_is_disjoint | 9.80 | 10.43 | 6,43 %
2 parents 2310a95 + 4b6e11d commit e25e6bb

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

src/raw/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4439,11 +4439,13 @@ impl<T, A: Allocator> FusedIterator for RawDrain<'_, T, A> {}
44394439
/// created will be yielded by that iterator.
44404440
/// - The order in which the iterator yields buckets is unspecified and may
44414441
/// change in the future.
4442+
#[cfg(feature = "raw")]
44424443
pub struct RawIterHash<T> {
44434444
inner: RawIterHashInner,
44444445
_marker: PhantomData<T>,
44454446
}
44464447

4448+
#[cfg(feature = "raw")]
44474449
struct RawIterHashInner {
44484450
// See `RawTableInner`'s corresponding fields for details.
44494451
// We can't store a `*const RawTableInner` as it would get
@@ -4463,19 +4465,20 @@ struct RawIterHashInner {
44634465
bitmask: BitMaskIter,
44644466
}
44654467

4468+
#[cfg(feature = "raw")]
44664469
impl<T> RawIterHash<T> {
44674470
#[cfg_attr(feature = "inline-more", inline)]
4468-
#[cfg(feature = "raw")]
44694471
unsafe fn new<A: Allocator>(table: &RawTable<T, A>, hash: u64) -> Self {
44704472
RawIterHash {
44714473
inner: RawIterHashInner::new(&table.table, hash),
44724474
_marker: PhantomData,
44734475
}
44744476
}
44754477
}
4478+
4479+
#[cfg(feature = "raw")]
44764480
impl RawIterHashInner {
44774481
#[cfg_attr(feature = "inline-more", inline)]
4478-
#[cfg(feature = "raw")]
44794482
unsafe fn new(table: &RawTableInner, hash: u64) -> Self {
44804483
let h2_hash = h2(hash);
44814484
let probe_seq = table.probe_seq(hash);
@@ -4493,6 +4496,7 @@ impl RawIterHashInner {
44934496
}
44944497
}
44954498

4499+
#[cfg(feature = "raw")]
44964500
impl<T> Iterator for RawIterHash<T> {
44974501
type Item = Bucket<T>;
44984502

@@ -4512,6 +4516,7 @@ impl<T> Iterator for RawIterHash<T> {
45124516
}
45134517
}
45144518

4519+
#[cfg(feature = "raw")]
45154520
impl Iterator for RawIterHashInner {
45164521
type Item = usize;
45174522

src/set.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,7 @@ where
10441044
/// assert_eq!(a.is_disjoint(&b), false);
10451045
/// ```
10461046
pub fn is_disjoint(&self, other: &Self) -> bool {
1047-
self.iter().all(|v| !other.contains(v))
1047+
self.intersection(other).next().is_none()
10481048
}
10491049

10501050
/// Returns `true` if the set is a subset of another,

0 commit comments

Comments
 (0)