Can I efficiently return an object by value in Rust?
Solution 1:
Yes, by all means, you should write
fn initialize() -> Vec<Vec<MyStruct>> { ... }
(By the way, a Vec
is not that large - it's only 3 pointer-sized integers)
Rust has RVO, and this is advertised in guides. You can see it yourself with this code:
#[inline(never)]
fn initialize() -> Vec<i32> {
Vec::new()
}
fn main() {
let v = initialize();
}
If you compile this program in release mode on the playground, outputting assembly, among everything else you will see this:
playground::initialize:
movq $4, (%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 8(%rdi)
retq
Vec::new()
was inlined, but you can see the idea - the address for the fresh Vec
instance is passed into the function in %rdi
, and the function stores Vec
fields directly into this memory, avoiding unnecessary copying through the stack. This is how it is called:
playground::main:
subq $24, %rsp
movq %rsp, %rdi
callq playground::initialize
You can see that eventually the Vec
instance will be put directly into the stack memory.