Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Optimization 我能否有效地按Rust中的值返回对象?_Optimization_Rust_Return Value Optimization - Fatal编程技术网

Optimization 我能否有效地按Rust中的值返回对象?

Optimization 我能否有效地按Rust中的值返回对象?,optimization,rust,return-value-optimization,Optimization,Rust,Return Value Optimization,我想用一个函数初始化一个大对象。目前我有: fn initialize(mydata: &mut Vec<Vec<MyStruct>>) { /* ... */ } fn初始化(mydata:&mut-Vec){/*…*/} 我希望: fn initialize() -> Vec<Vec<MyStruct>> { /* ... */ } fn initialize()->Vec{/*…*/} 我听说如果你运气好,有一个好的编译

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

fn initialize(mydata: &mut Vec<Vec<MyStruct>>) { /* ... */ }
fn初始化(mydata:&mut-Vec){/*…*/}
我希望:

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

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

是的,无论如何,您应该编写

fn initialize() -> Vec<Vec<MyStruct>> { ... }
如果您在发布模式下编译此程序,输出程序集等,您将看到:

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

建议RVO触发大于指针的任何内容。但也有关于NRVO的问题。所以我想这完全取决于您如何实现
initialize
。可能吧,但我发现LLVM IR的读取比程序集要困难得多,因为某些原因:(为此,我们只需要签名:
define internal fastcc void@initialize(%)struct.collections::vec::vec[#3]“*noalias nocapture sret dereferenceable(24))unnamed_addr#0
。LLVM IR对于声明类似于C,因此该函数返回
void
,并将指针(
*
)带到
结构集合::vec::vec
(为了更清楚起见,我使用了
.[no\u mangle]
)这可能会显示传递一个指针,但如果您查看LLVM IR的末尾,您可能会看到内存块或类似内存块中有一个memcpy。我有一段代码,分配了一个256 int数组以返回,如果您查看IR的底部,您会看到从一个对象到另一个对象的副本。查看生成的ASM(在play.r-l.org上有beta版和夜间版),你可以看到mempcy@PLT在函数调用的底部。
playground::main:
    subq    $24, %rsp
    movq    %rsp, %rdi
    callq   playground::initialize