about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrew Paseltiner <apaseltiner@gmail.com>2016-02-16 18:20:35 -0500
committerAndrew Paseltiner <apaseltiner@gmail.com>2016-02-16 18:40:10 -0500
commitf890772383c900f9a409a4105df13b6630ebb1f5 (patch)
tree6ded921b2ac737d72e8900e7d451b4f7a0780c69
parent9658645407c784105bb361297d5316cadc9ff2bd (diff)
downloadrust-f890772383c900f9a409a4105df13b6630ebb1f5.tar.gz
rust-f890772383c900f9a409a4105df13b6630ebb1f5.zip
Avoid iteration when dropping `HashMap`s whose items don't need dropping
This changes the performance of `drop` from linear to constant time for
such `HashMap`s.

Closes #31711.
-rw-r--r--src/libstd/collections/hash/table.rs5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 316c7595266..97cab94b67b 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -12,6 +12,7 @@ use alloc::heap::{allocate, deallocate, EMPTY};
 
 use cmp;
 use hash::{Hash, Hasher, BuildHasher};
+use intrinsics::needs_drop;
 use marker;
 use mem::{align_of, size_of};
 use mem;
@@ -1009,7 +1010,9 @@ impl<K, V> Drop for RawTable<K, V> {
         // dropping empty tables such as on resize.
         // Also avoid double drop of elements that have been already moved out.
         unsafe {
-            for _ in self.rev_move_buckets() {}
+            if needs_drop::<(K, V)>() { // avoid linear runtime for types that don't need drop
+                for _ in self.rev_move_buckets() {}
+            }
         }
 
         let hashes_size = self.capacity * size_of::<u64>();