about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-09-20 06:29:42 +0000
committerbors <bors@rust-lang.org>2017-09-20 06:29:42 +0000
commit94a82adbb491b5fd0585370d4fcc7b36798e70d5 (patch)
treede14b4b931e0cea4245b79eb557ab7cce878c959 /src/liballoc
parent54996837a399421f8d691c6901eea5ab20a30f46 (diff)
parent10384ab18a386e6f7b58c714def62e405182d968 (diff)
downloadrust-94a82adbb491b5fd0585370d4fcc7b36798e70d5.tar.gz
rust-94a82adbb491b5fd0585370d4fcc7b36798e70d5.zip
Auto merge of #44355 - Xaeroxe:optimize_drain_filter, r=alexcrichton
Optimize drain_filter

This PR cuts out two copies from each iteration of `drain_filter` by exchanging the swap operation for a copy_nonoverlapping function call instead.  Since the data being swapped is not needed anymore we can just overwrite it instead.
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/vec.rs8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 75d54b82076..7dd8895c1ae 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2694,7 +2694,13 @@ impl<'a, T, F> Iterator for DrainFilter<'a, T, F>
                     self.del += 1;
                     return Some(ptr::read(&v[i]));
                 } else if self.del > 0 {
-                    v.swap(i - self.del, i);
+                    let del = self.del;
+                    let src: *const T = &v[i];
+                    let dst: *mut T = &mut v[i - del];
+                    // This is safe because self.vec has length 0
+                    // thus its elements will not have Drop::drop
+                    // called on them in the event of a panic.
+                    ptr::copy_nonoverlapping(src, dst, 1);
                 }
             }
             None