optimization rust return-value-optimization

optimization - ¿Puedo devolver eficientemente un objeto por valor en Rust?



return-value-optimization (1)

Me gustaría inicializar un objeto grande con una función. Actualmente tengo:

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

Prefiero tener:

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

Escuché que C ++ a menudo implementa la optimización del valor de retorno (RVO), si tienes suerte y tienes un buen compilador. ¿Podemos desactivar la copia aquí y que sea devuelta por un puntero oculto que se pasa a la función? ¿RVO es parte del lenguaje o una optimización opcional?


Sí, por supuesto, deberías escribir

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

(Por cierto, un Vec no es tan grande, solo tiene 3 enteros del tamaño de un puntero)

Rust tiene RVO, y esto se anuncia en guías . Puede verlo usted mismo con este código:

#[inline(never)] fn initialize() -> Vec<i32> { Vec::new() } fn main() { let v = initialize(); }

Si compila este programa en modo de lanzamiento en el patio de juegos , generando ensamblaje, entre todo lo demás verá esto:

playground::initialize: movq $4, (%rdi) xorps %xmm0, %xmm0 movups %xmm0, 8(%rdi) retq

Vec::new() estaba en línea, pero puede ver la idea: la dirección de la nueva instancia de Vec se pasa a la función en %rdi , y la función almacena los campos Vec directamente en esta memoria, evitando copias innecesarias a través de la pila. Así es como se llama:

playground::main: subq $24, %rsp movq %rsp, %rdi callq playground::initialize

Puede ver que eventualmente la instancia de Vec se colocará directamente en la memoria de la pila.