Ber*_*ard 3 performance clone copy rust
在 Rust 中,有两种方法可以从另一个切片更新切片的内容:clone_from_slice()和copy_from_slice(). 这两个函数的行为并不奇怪 - 第一个执行克隆并期望类型实现Clone,而第二个执行复制并期望类型实现Copy。
然而,令我惊讶的是,它的文档是这样clone_from_slice说的:“如果T实现了Copy,使用它可以提高性能copy_from_slice。” 令人惊讶的是,这里应该存在性能差异。如果Timplements Copy,则.clone()要求相当于复制位;但是,由于编译器知道是什么类型T,因此即使我使用clone_from_slice.
那么性能低效从何而来?
TL;DR 请检查clone_from_slice的来源,它是访问 slice 的所有元素并调用clone每个元素,而copy_from_slice直接复制所有位memcpy。
如果 T 实现
Copy,则.clone()需要等效于复制位
即使每个Copy类型都会Clone默认实现whereclone直接使用copy; clone_from_slice仍然会遍历切片并在遍历时进行复制。
但是没有这个命题对于原语是正确的,但对于以下情况不正确:
#[derive(Copy)]
struct X;
impl Clone for X {
fn clone(&self) -> Self {
//do some heavy operation or light(depends on the logic)
X
}
}
Run Code Online (Sandbox Code Playgroud)
虽然Clone可以由任何逻辑Copy类型实现,但在复制对象时只会复制位。
如果 T 实现
Copy,则使用它可以提高性能copy_from_slice
重要的是在这里,文档说“它可以”不是“它会是”,这带来了像
Cloneimplementation 可以直接使用Copyimplementation。对于基本类型如原语,优化器可能会直接使用memcpy而不是遍历,那么我们可能会认为这个命题是错误的,因为一个不会比另一个更好。
Cloneimplementation 可以直接使用Copyimplementation。对于复杂类型(上面的遍历问题),这个命题是正确的。(我用更复杂的结构编辑了@kmdreko的例子,请检查 Godbolt 的结果)
Clone实现是自定义的并且它是一种Copy类型,即使自定义实现不昂贵,这将使这个命题正确,然后copy对于大切片使用memcpy可能更有益。
| 归档时间: |
|
| 查看次数: |
383 次 |
| 最近记录: |