gpt4 book ai didi

rust - 移动变量时会逐字节复制数据吗?

转载 作者:行者123 更新时间:2023-12-05 01:06:02 24 4
gpt4 key购买 nike

我是 rust 新手,我想知道移动变量时究竟会发生什么。

struct Point {
x: i32,
y: i32,
}

fn main() {
let p = Point { x: 1, y: 1 };
let q = p;
}

let q = p;时,数据(大小为8字节)是否会从一个内存地址复制到另一个?由于 p 被移到了这里,所以不能再使用了,我认为最好让 q 的底层内存地址等于 p' s。换句话说,我认为机器码中没有任何复制是可以的。

所以我的问题是:移动变量时会逐字节复制数据吗?如果会,为什么?

最佳答案

[W]ill data be copied byte by byte when moving a variable?

一般来说,是的。为了移动一个值,Rust 只需执行按位复制。如果该值不是 Copy,则移动后将不再使用源。如果值为Copy,则源和目标都可以使用。

但是,在很多情况下,编译器后端可以通过证明没有副本的代码行为相同来消除副本。这种优化完全发生在 LLVM 中。在您的示例中,LLVM IR 仍然包含移动数据的指令,但生成的代码即使在 Debug模式下也不包含移动。

If it will, why?

编译器无法将相同的内存用于源和目标的原因有很多。在您的示例中,在同一个堆栈帧中有两个变量,很容易看出不需要移动,但无论如何代码有点毫无意义(尽管有时人们会在函数内移动值以使变量不可变)。

以下只是编译器可能无法将源内存重用于目标的几个说明:

  • 源值可能在堆栈上,而目标值在堆上,反之亦然。语句 let b = Box::new(3); 会将值 3 从堆栈移动到堆'; let i = *b; 会将其从堆移回堆栈。 可能编译器可以消除这些 Action ,例如通过立即将常量 3 写入堆,而不先将其写入堆栈。

  • 在跨函数移动值时,源和目标可能位于不同的堆栈帧上——例如将值传递给函数时,或从函数返回值时。

  • 源和目标值可能存储在结构字段中,因此它们需要在结构内具有正确的偏移量。

这些只是几个例子。要点是,一般来说,移动可能会导致按位复制。但是请记住,按位复制非常便宜,而且优化器通常做得很好,所以只有在确实存在性能瓶颈时才应该担心这一点。

关于rust - 移动变量时会逐字节复制数据吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70034918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com