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 1/2] 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 e14ebd869a308..e5441f13870e3 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) } } From 94d6b22fc36f50b021e47eae2a9437689ee83077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Thu, 12 Aug 2021 10:48:04 +0200 Subject: [PATCH 2/2] Add missing cfg attribute --- library/alloc/src/vec/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index e5441f13870e3..933361d812cb0 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2378,10 +2378,12 @@ impl ops::DerefMut for Vec { } } +#[cfg(not(no_global_oom_handling))] trait SpecCloneFrom { fn clone_from(this: &mut Self, other: &Self); } +#[cfg(not(no_global_oom_handling))] impl SpecCloneFrom for Vec { default fn clone_from(this: &mut Self, other: &Self) { // drop anything that will not be overwritten @@ -2397,6 +2399,7 @@ impl SpecCloneFrom for Vec { } } +#[cfg(not(no_global_oom_handling))] impl SpecCloneFrom for Vec { fn clone_from(this: &mut Self, other: &Self) { this.clear();