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

2024-04-24

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

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

我更愿意拥有:

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

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


是的,无论如何,你应该写

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

(顺便说一下,一个Vec没那么大——只有 3 个指针大小的整数)

Rust 有 RVO,这个在指南中刊登广告 https://web.archive.org/web/20141225073722/https://doc.rust-lang.org/guide-pointers.html#returning-pointers。您可以通过以下代码亲自查看:

#[inline(never)]
fn initialize() -> Vec<i32> {
    Vec::new()
}

fn main() {
    let v = initialize();
}

如果你在release模式下编译这个程序,输出程序集,除此之外你会看到这个:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以在 Rust 中有效地按值返回对象吗? 的相关文章

随机推荐