From 361398009be65f9aa6ae539c2ea37fbd943cc789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Tue, 10 Aug 2021 11:45:52 +0200 Subject: [PATCH] Specialize `Vec::clone_from` for `Copy` types This should improve performance and reduce code size. This also improves `clone_from` for `String`, `OsString` and `PathBuf`. --- library/alloc/src/vec/mod.rs | 37 ++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index e14ebd869a30..e5441f13870e 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2378,6 +2378,32 @@ impl ops::DerefMut for Vec { } } +trait SpecCloneFrom { + fn clone_from(this: &mut Self, other: &Self); +} + +impl SpecCloneFrom for Vec { + default fn clone_from(this: &mut Self, other: &Self) { + // drop anything that will not be overwritten + this.truncate(other.len()); + + // self.len <= other.len due to the truncate above, so the + // slices here are always in-bounds. + let (init, tail) = other.split_at(this.len()); + + // reuse the contained values' allocations/resources. + this.clone_from_slice(init); + this.extend_from_slice(tail); + } +} + +impl SpecCloneFrom for Vec { + fn clone_from(this: &mut Self, other: &Self) { + this.clear(); + this.extend_from_slice(other); + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Vec { @@ -2398,16 +2424,7 @@ impl Clone for Vec { } fn clone_from(&mut self, other: &Self) { - // drop anything that will not be overwritten - self.truncate(other.len()); - - // self.len <= other.len due to the truncate above, so the - // slices here are always in-bounds. - let (init, tail) = other.split_at(self.len()); - - // reuse the contained values' allocations/resources. - self.clone_from_slice(init); - self.extend_from_slice(tail); + SpecCloneFrom::clone_from(self, other) } }