]> git.lizzy.rs Git - rust.git/commitdiff
Optimize `Vec::clone_from`
authorAndrew Paseltiner <apaseltiner@gmail.com>
Wed, 23 Sep 2015 14:33:36 +0000 (10:33 -0400)
committerAndrew Paseltiner <apaseltiner@gmail.com>
Thu, 24 Sep 2015 12:47:33 +0000 (08:47 -0400)
Before:

test dst_bigger::src_100_dst_1000::clone      ... bench:  34 ns/iter (+/- 1)
test dst_bigger::src_100_dst_1000::clone_from ... bench:  75 ns/iter (+/- 3)

test dst_bigger::src_10_dst_100::clone        ... bench:  25 ns/iter (+/- 0)
test dst_bigger::src_10_dst_100::clone_from   ... bench:   9 ns/iter (+/- 1)

test eq::src_1000_dst_1000::clone             ... bench: 105 ns/iter (+/- 2)
test eq::src_1000_dst_1000::clone_from        ... bench: 593 ns/iter (+/- 21)

test eq::src_100_dst_100::clone               ... bench:  34 ns/iter (+/- 1)
test eq::src_100_dst_100::clone_from          ... bench:  75 ns/iter (+/- 1)

test src_bigger::src_1000_dst_100::clone      ... bench: 103 ns/iter (+/- 5)
test src_bigger::src_1000_dst_100::clone_from ... bench: 148 ns/iter (+/- 5)

test src_bigger::src_100_dst_10::clone        ... bench:  34 ns/iter (+/- 1)
test src_bigger::src_100_dst_10::clone_from   ... bench:  20 ns/iter (+/- 0)

After:

test dst_bigger::src_100_dst_1000::clone      ... bench:  34 ns/iter (+/- 2)
test dst_bigger::src_100_dst_1000::clone_from ... bench:  15 ns/iter (+/- 1)

test dst_bigger::src_10_dst_100::clone        ... bench:  26 ns/iter (+/- 1)
test dst_bigger::src_10_dst_100::clone_from   ... bench:   7 ns/iter (+/- 0)

test eq::src_1000_dst_1000::clone             ... bench: 103 ns/iter (+/- 1)
test eq::src_1000_dst_1000::clone_from        ... bench:  85 ns/iter (+/- 4)

test eq::src_100_dst_100::clone               ... bench:  34 ns/iter (+/- 2)
test eq::src_100_dst_100::clone_from          ... bench:  15 ns/iter (+/- 1)

test src_bigger::src_1000_dst_100::clone      ... bench: 103 ns/iter (+/- 4)
test src_bigger::src_1000_dst_100::clone_from ... bench:  90 ns/iter (+/- 2)

test src_bigger::src_100_dst_10::clone        ... bench:  34 ns/iter (+/- 2)
test src_bigger::src_100_dst_10::clone_from   ... bench:  20 ns/iter (+/- 0)

Closes #28601.

src/libcollections/lib.rs
src/libcollections/vec.rs

index 34bd1345fcb3b24bac59adea1ef5c4cb95cbb18c..03ee8ba31b1d21d6648561651a6ccb2fd7ddb07a 100644 (file)
@@ -62,7 +62,7 @@
 #![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(decode_utf16)]
 #![feature(utf8_error)]
-#![cfg_attr(test, feature(rand, test))]
+#![cfg_attr(test, feature(clone_from_slice, rand, test))]
 
 #![feature(no_std)]
 #![no_std]
index 4110faa41b32473520319d94b84118dbfb228267..de3e6f94e874645abc6ff7c0d823ae9c32adad31 100644 (file)
@@ -1007,19 +1007,15 @@ fn clone(&self) -> Vec<T> {
 
     fn clone_from(&mut self, other: &Vec<T>) {
         // drop anything in self that will not be overwritten
-        if self.len() > other.len() {
-            self.truncate(other.len())
-        }
+        self.truncate(other.len());
+        let len = self.len();
 
         // reuse the contained values' allocations/resources.
-        for (place, thing) in self.iter_mut().zip(other) {
-            place.clone_from(thing)
-        }
+        self.clone_from_slice(&other[..len]);
 
         // self.len <= other.len due to the truncate above, so the
         // slice here is always in-bounds.
-        let slice = &other[self.len()..];
-        self.push_all(slice);
+        self.push_all(&other[len..]);
     }
 }