有朝一日,Rust 可以在对象移动期间优化掉按位复制吗?

Can Rust optimise away the bit-wise copy during move of an object someday?

考虑片段

struct Foo {
    dummy: [u8; 65536],
}

fn bar(foo: Foo) {
    println!("{:p}", &foo)
}

fn main() {
    let o = Foo { dummy: [42u8; 65536] };
    println!("{:p}", &o);
    bar(o);
}

一个典型的result程序是

0x7fffc1239890
0x7fffc1229890

地址不同。

显然,大数组 dummy 已被复制,正如编译器的移动实现所预期的那样。不幸的是,这会对性能产生重大影响,因为 dummy 是一个非常大的数组。这种影响会迫使人们选择通过引用传递参数,即使函数实际上 "consumes" 概念上的参数。

由于 Foo 不派生 Copy,对象 o 被移动。由于 Rust 禁止访问移动的对象,是什么阻止了 bar 到 "reuse" 原始对象 o,迫使编译器生成一个潜在的昂贵的按位副本?是否存在基本困难,或者我们有一天会看到编译器优化掉这个按位复制?

鉴于在 Rust 中(与 C 或 C++ 不同)值的地址不被认为是重要的,语言 没有任何东西可以防止复制的省略.

然而,今天 rustc 没有优化任何东西:所有的优化都委托给了 LLVM,你似乎在这里遇到了 LLVM 优化器的限制(目前还不清楚这个限制是由于 LLVM 接近 C 的语义还是只是一个遗漏)。

因此,有两种改进代码生成的途径:

  • 教 LLVM 执行此优化(如果可能)
  • 教 rustc 执行此优化(优化过程即将进入 rustc,因为它有 MIR)

但现在您可能只是想避免在堆栈上分配如此大的对象,您可以 Box 例如。