From a03287bbf765ce7ac0e2ae9e64d8ade168ece301 Mon Sep 17 00:00:00 2001 From: Cheng XU Date: Sat, 28 Aug 2021 16:57:58 -0700 Subject: [PATCH] BTreeSet::from_iter: use bulk building to improve the performance Apply the same optimization as BTreeMap::from_iter. --- library/alloc/src/collections/btree/set.rs | 27 ++++++++++++++++++---- 1 file 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 @@ pub const fn is_empty(&self) -> bool { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BTreeSet { fn from_iter>(iter: I) -> BTreeSet { - 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 @@ fn from_iter>(iter: I) -> BTreeSet { /// 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 } } }