diff options
| author | arthurprs <arthurprs@gmail.com> | 2016-11-26 17:30:29 +0100 |
|---|---|---|
| committer | arthurprs <arthurprs@gmail.com> | 2016-12-06 10:14:59 +0100 |
| commit | 2c5d2403d770e624bbb0b9ce8e970efa914a8602 (patch) | |
| tree | fe7f71e99197ae0bda628b3d99cf5b311255a268 /src/libstd | |
| parent | 73e98a0210f0afdec28b4f5bc0f7327d6a5a8555 (diff) | |
| download | rust-2c5d2403d770e624bbb0b9ce8e970efa914a8602.tar.gz rust-2c5d2403d770e624bbb0b9ce8e970efa914a8602.zip | |
Smarter HashMap/HashSet extend
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/collections/hash/map.rs | 17 | ||||
| -rw-r--r-- | src/libstd/collections/hash/set.rs | 10 |
2 files changed, 16 insertions, 11 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index ece51d6d826..9f9d0429fca 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -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 } } @@ -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); } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 1ec7a4a7b63..72af612f569 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -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 } } @@ -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, ()))); } } |
