考虑一下片段
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);
}程序的一个典型的结果是
0x7fffc1239890
0x7fffc1229890地址不同的地方。
显然,大型数组dummy已被复制,正如编译器的move实现中所期望的那样。不幸的是,这可能会对性能产生重要影响,因为dummy是一个非常大的数组.这种影响可以迫使人们选择通过引用传递参数,即使函数实际上在概念上“消耗”参数。
由于Foo不派生Copy,因此将移动对象o。由于Rust禁止访问移动对象,是什么阻止bar“重用”原始对象o,迫使编译器生成一个可能昂贵的位级副本?有根本的困难吗,或者我们会看到编译器有一天会优化这个明智的拷贝吗?
发布于 2016-07-25 15:19:00
考虑到在Rust (与C或C++不同)中,值的地址并不重要,在语言方面没有什么能阻止副本的省略。
然而,今天rustc并没有优化任何东西:所有的优化都委托给LLVM,而且这里似乎遇到了LLVM优化器的一个限制(不清楚这个限制是因为LLVM接近C的语义,还是只是一个遗漏)。
因此,有两种改进代码生成的方法:
但就目前而言,您可能只想避免在堆栈上分配这么大的对象,例如,您可以Box它。
https://stackoverflow.com/questions/38571270
复制相似问题