Skip to content

Commit

Permalink
Smarter HashMap/HashSet extend
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurprs committed Dec 6, 2016
1 parent 73e98a0 commit 2c5d240
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
17 changes: 13 additions & 4 deletions src/libstd/collections/hash/map.rs
Expand Up @@ -1971,10 +1971,8 @@ impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
S: BuildHasher + Default
{
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> HashMap<K, V, S> {
let iterator = iter.into_iter();
let lower = iterator.size_hint().0;
let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
map.extend(iterator);
let mut map = HashMap::with_hasher(Default::default());
map.extend(iter);
map
}
}
Expand All @@ -1985,6 +1983,17 @@ impl<K, V, S> Extend<(K, V)> for HashMap<K, V, S>
S: BuildHasher
{
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
// Keys may be already present or show multiple times in the iterator.
// Reserve the entire hint lower bound if the map is empty.
// Otherwise reserve half the hint (rounded up), so the map
// will only resize twice in the worst case.
let iter = iter.into_iter();
let reserve = if self.is_empty() {
iter.size_hint().0
} else {
(iter.size_hint().0 + 1) / 2
};
self.reserve(reserve);
for (k, v) in iter {
self.insert(k, v);
}
Expand Down
10 changes: 3 additions & 7 deletions src/libstd/collections/hash/set.rs
Expand Up @@ -663,10 +663,8 @@ impl<T, S> FromIterator<T> for HashSet<T, S>
S: BuildHasher + Default
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> HashSet<T, S> {
let iterator = iter.into_iter();
let lower = iterator.size_hint().0;
let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
set.extend(iterator);
let mut set = HashSet::with_hasher(Default::default());
set.extend(iter);
set
}
}
Expand All @@ -677,9 +675,7 @@ impl<T, S> Extend<T> for HashSet<T, S>
S: BuildHasher
{
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for k in iter {
self.insert(k);
}
self.map.extend(iter.into_iter().map(|k| (k, ())));
}
}

Expand Down

0 comments on commit 2c5d240

Please sign in to comment.