diff options
| author | Cheng XU <git@xuc.me> | 2021-08-28 16:57:58 -0700 |
|---|---|---|
| committer | Cheng XU <git@xuc.me> | 2021-08-28 17:19:07 -0700 |
| commit | a03287bbf765ce7ac0e2ae9e64d8ade168ece301 (patch) | |
| tree | 03d6e4dd77936de49c41a8570aee2d28c03b1490 | |
| parent | cf814d60f82723e5965763859c51b3e7bd885b9b (diff) | |
| download | rust-a03287bbf765ce7ac0e2ae9e64d8ade168ece301.tar.gz rust-a03287bbf765ce7ac0e2ae9e64d8ade168ece301.zip | |
BTreeSet::from_iter: use bulk building to improve the performance
Apply the same optimization as BTreeMap::from_iter.
| -rw-r--r-- | library/alloc/src/collections/btree/set.rs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 0c268ad32b2..fca281a63bb 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1,6 +1,7 @@ // This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface // to TreeMap +use crate::vec::Vec; use core::borrow::Borrow; use core::cmp::Ordering::{Equal, Greater, Less}; use core::cmp::{max, min}; @@ -1059,9 +1060,17 @@ impl<T> BTreeSet<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: Ord> FromIterator<T> for BTreeSet<T> { fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> BTreeSet<T> { - let mut set = BTreeSet::new(); - set.extend(iter); - set + let mut inputs: Vec<_> = iter.into_iter().collect(); + + if inputs.is_empty() { + return BTreeSet::new(); + } + + // use stable sort to preserve the insertion order. + inputs.sort(); + let iter = inputs.into_iter().map(|k| (k, ())); + let map = BTreeMap::bulk_build_from_sorted_iter(iter); + BTreeSet { map } } } @@ -1074,8 +1083,16 @@ impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> { /// let set2: BTreeSet<_> = [1, 2, 3, 4].into(); /// assert_eq!(set1, set2); /// ``` - fn from(arr: [T; N]) -> Self { - core::array::IntoIter::new(arr).collect() + fn from(mut arr: [T; N]) -> Self { + if N == 0 { + return BTreeSet::new(); + } + + // use stable sort to preserve the insertion order. + arr.sort(); + let iter = core::array::IntoIter::new(arr).map(|k| (k, ())); + let map = BTreeMap::bulk_build_from_sorted_iter(iter); + BTreeSet { map } } } |
