我想用函数初始化一个大对象。目前我有:
fn initialize(mydata: &mut Vec<Vec<MyStruct>>) { /* ... */ }
我更愿意:
fn initialize() -> Vec<Vec<MyStruct>> { /* ... */ }
我听说C ++经常实现返回值优化(RVO),如果你很幸运并拥有一个好的编译器。我们可以在这里禁用复制并通过传递给函数的隐藏指针返回吗? RVO是语言的一部分还是可选的优化?
答案 0 :(得分:13)
是的,无论如何,你应该写
fn initialize() -> Vec<Vec<MyStruct>> { ... }
(顺便说一下,Vec
不是那么大 - 它只有3个指针大小的整数)
Rust有RVO,这个is advertised in guides。您可以使用以下代码自行查看:
#[inline(never)]
fn initialize() -> Vec<i32> {
Vec::new()
}
fn main() {
let v = initialize();
}
如果你以发布模式on the playground编译这个程序,输出程序集,除此之外你会看到:
playground::initialize:
movq $4, (%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 8(%rdi)
retq
Vec::new()
已内联,但您可以看到这个想法 - 新Vec
实例的地址传递到%rdi
中的函数,函数存储Vec
字段直接进入此内存,避免通过堆栈进行不必要的复制。这就是它的名称:
playground::main:
subq $24, %rsp
movq %rsp, %rdi
callq playground::initialize
您可以看到最终Vec
实例将直接放入堆栈内存。