我可以在Rust中按值有效地返回一个对象吗?

时间:2015-01-08 07:55:30

标签: optimization rust return-value-optimization

我想用函数初始化一个大对象。目前我有:

fn initialize(mydata: &mut Vec<Vec<MyStruct>>) { /* ... */ }

我更愿意:

fn initialize() -> Vec<Vec<MyStruct>> { /* ... */ }

我听说C ++经常实现返回值优化(RVO),如果你很幸运并拥有一个好的编译器。我们可以在这里禁用复制并通过传递给函数的隐藏指针返回吗? RVO是语言的一部分还是可选的优化?

1 个答案:

答案 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实例将直接放入堆栈内存。