Skip to content

Commit ab3e4ea

Browse files
bors[bot]Amanieu
andcommitted
Merge #61
61: Improve worst-case performance of HashSet.is_subset r=Amanieu a=Amanieu Ported from rust-lang/rust#59665 Co-authored-by: Amanieu d'Antras <[email protected]>
2 parents 9068eb7 + 9facea7 commit ab3e4ea

File tree

4 files changed

+20
-12
lines changed

4 files changed

+20
-12
lines changed

src/external_trait_impls/rayon/set.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,11 @@ where
256256
///
257257
/// This method runs in a potentially parallel fashion.
258258
pub fn par_is_subset(&self, other: &Self) -> bool {
259-
self.into_par_iter().all(|x| other.contains(x))
259+
if self.len() <= other.len() {
260+
self.into_par_iter().all(|x| other.contains(x))
261+
} else {
262+
false
263+
}
260264
}
261265

262266
/// Returns `true` if the set is a superset of another,

src/map.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,8 +1646,8 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
16461646
{
16471647
unsafe {
16481648
let elem = self.table.insert(hash, (key, value), |x| hasher(&x.0));
1649-
let &mut (ref mut key, ref mut value) = elem.as_mut();
1650-
(key, value)
1649+
let &mut (ref mut k, ref mut v) = elem.as_mut();
1650+
(k, v)
16511651
}
16521652
}
16531653
}

src/raw/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ fn h2(hash: u64) -> u8 {
145145
/// (skipping over 1 group), then 3 groups (skipping over 2 groups), and so on.
146146
///
147147
/// Proof that the probe will visit every group in the table:
148-
/// https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/
148+
/// <https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/>
149149
struct ProbeSeq {
150150
bucket_mask: usize,
151151
pos: usize,
@@ -298,7 +298,7 @@ impl<T> Bucket<T> {
298298
} else {
299299
self.ptr.add(offset)
300300
};
301-
Bucket { ptr }
301+
Self { ptr }
302302
}
303303
#[inline]
304304
pub unsafe fn drop(&self) {
@@ -321,7 +321,7 @@ impl<T> Bucket<T> {
321321
&mut *self.as_ptr()
322322
}
323323
#[inline]
324-
pub unsafe fn copy_from_nonoverlapping(&self, other: Bucket<T>) {
324+
pub unsafe fn copy_from_nonoverlapping(&self, other: &Self) {
325325
self.as_ptr().copy_from_nonoverlapping(other.as_ptr(), 1);
326326
}
327327
}
@@ -745,7 +745,7 @@ impl<T> RawTable<T> {
745745
// element into the new slot and clear the old control
746746
// byte.
747747
guard.set_ctrl(i, EMPTY);
748-
guard.bucket(new_i).copy_from_nonoverlapping(item);
748+
guard.bucket(new_i).copy_from_nonoverlapping(&item);
749749
continue 'outer;
750750
} else {
751751
// If the target slot is occupied, swap the two elements
@@ -802,7 +802,7 @@ impl<T> RawTable<T> {
802802
// - all elements are unique.
803803
let index = new_table.find_insert_slot(hash);
804804
new_table.set_ctrl(index, h2(hash));
805-
new_table.bucket(index).copy_from_nonoverlapping(item);
805+
new_table.bucket(index).copy_from_nonoverlapping(&item);
806806
}
807807

808808
// We successfully copied all elements without panicking. Now replace
@@ -935,12 +935,12 @@ impl<T> RawTable<T> {
935935
/// should be dropped using a `RawIter` before freeing the allocation.
936936
#[inline]
937937
pub fn into_alloc(self) -> Option<(NonNull<u8>, Layout)> {
938-
let alloc = if !self.is_empty_singleton() {
938+
let alloc = if self.is_empty_singleton() {
939+
None
940+
} else {
939941
let (layout, _) = calculate_layout::<T>(self.buckets())
940942
.unwrap_or_else(|| unsafe { hint::unreachable_unchecked() });
941943
Some((self.ctrl.cast(), layout))
942-
} else {
943-
None
944944
};
945945
mem::forget(self);
946946
alloc

src/set.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,11 @@ where
640640
/// assert_eq!(set.is_subset(&sup), false);
641641
/// ```
642642
pub fn is_subset(&self, other: &Self) -> bool {
643-
self.iter().all(|v| other.contains(v))
643+
if self.len() <= other.len() {
644+
self.iter().all(|v| other.contains(v))
645+
} else {
646+
false
647+
}
644648
}
645649

646650
/// Returns `true` if the set is a superset of another,

0 commit comments

Comments
 (0)