Skip to content

Commit

Permalink
Auto merge of #87913 - a1phyr:vec_spec_clone_from, r=dtolnay
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
bors committed Aug 14, 2021
2 parents 136eaa1 + 94d6b22 commit a59e885
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2378,6 +2378,35 @@ impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
}
}

#[cfg(not(no_global_oom_handling))]
trait SpecCloneFrom {
fn clone_from(this: &mut Self, other: &Self);
}

#[cfg(not(no_global_oom_handling))]
impl<T: Clone, A: Allocator> SpecCloneFrom for Vec<T, A> {
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);
}
}

#[cfg(not(no_global_oom_handling))]
impl<T: Copy, A: Allocator> SpecCloneFrom for Vec<T, A> {
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<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
Expand All @@ -2398,16 +2427,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
}

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)
}
}

Expand Down

0 comments on commit a59e885

Please sign in to comment.