Skip to content

Commit

Permalink
Auto merge of rust-lang#97868 - ssomers:btree_from_sorted_iter, r=the…
Browse files Browse the repository at this point in the history
…8472

BTreeSet: avoid intermediate sorting when collecting sorted iterators

As [pointed out by droundy](https://users.rust-lang.org/t/question-about-btreeset-implementation/76427), an obvious optimization is to skip the first step introduced by rust-lang#88448 (creation of a vector and sorting) and it's easy to do so for btree's own iterators. Also, exploit `from` in the examples.
  • Loading branch information
bors committed Jun 9, 2022
2 parents 6dc598a + 49ccb75 commit be16c61
Showing 1 changed file with 15 additions and 13 deletions.
28 changes: 15 additions & 13 deletions library/alloc/src/collections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,13 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {

// use stable sort to preserve the insertion order.
inputs.sort();
let iter = inputs.into_iter().map(|k| (k, ()));
BTreeSet::from_sorted_iter(inputs.into_iter())
}
}

impl<T: Ord> BTreeSet<T> {
fn from_sorted_iter<I: Iterator<Item = T>>(iter: I) -> BTreeSet<T> {
let iter = iter.map(|k| (k, ()));
let map = BTreeMap::bulk_build_from_sorted_iter(iter);
BTreeSet { map }
}
Expand Down Expand Up @@ -1258,11 +1264,10 @@ impl<T: Ord + Clone> Sub<&BTreeSet<T>> for &BTreeSet<T> {
/// let b = BTreeSet::from([3, 4, 5]);
///
/// let result = &a - &b;
/// let result_vec: Vec<_> = result.into_iter().collect();
/// assert_eq!(result_vec, [1, 2]);
/// assert_eq!(result, BTreeSet::from([1, 2]));
/// ```
fn sub(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.difference(rhs).cloned().collect()
BTreeSet::from_sorted_iter(self.difference(rhs).cloned())
}
}

Expand All @@ -1281,11 +1286,10 @@ impl<T: Ord + Clone> BitXor<&BTreeSet<T>> for &BTreeSet<T> {
/// let b = BTreeSet::from([2, 3, 4]);
///
/// let result = &a ^ &b;
/// let result_vec: Vec<_> = result.into_iter().collect();
/// assert_eq!(result_vec, [1, 4]);
/// assert_eq!(result, BTreeSet::from([1, 4]));
/// ```
fn bitxor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.symmetric_difference(rhs).cloned().collect()
BTreeSet::from_sorted_iter(self.symmetric_difference(rhs).cloned())
}
}

Expand All @@ -1304,11 +1308,10 @@ impl<T: Ord + Clone> BitAnd<&BTreeSet<T>> for &BTreeSet<T> {
/// let b = BTreeSet::from([2, 3, 4]);
///
/// let result = &a & &b;
/// let result_vec: Vec<_> = result.into_iter().collect();
/// assert_eq!(result_vec, [2, 3]);
/// assert_eq!(result, BTreeSet::from([2, 3]));
/// ```
fn bitand(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.intersection(rhs).cloned().collect()
BTreeSet::from_sorted_iter(self.intersection(rhs).cloned())
}
}

Expand All @@ -1327,11 +1330,10 @@ impl<T: Ord + Clone> BitOr<&BTreeSet<T>> for &BTreeSet<T> {
/// let b = BTreeSet::from([3, 4, 5]);
///
/// let result = &a | &b;
/// let result_vec: Vec<_> = result.into_iter().collect();
/// assert_eq!(result_vec, [1, 2, 3, 4, 5]);
/// assert_eq!(result, BTreeSet::from([1, 2, 3, 4, 5]));
/// ```
fn bitor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.union(rhs).cloned().collect()
BTreeSet::from_sorted_iter(self.union(rhs).cloned())
}
}

Expand Down

0 comments on commit be16c61

Please sign in to comment.