rust: exemple simple d'utilisation de Cow

a marqué ce sujet comme résolu.

Salut,

J’imagine que tu parles de std::borrow::Cow de Rust.

Classiquement, on a besoin de copier std::clone::Clone un objet lorsqu’on désire conserver l’ancienne valeur (ce qui en Rust peut aussi bêtement servir à en garder l'ownership) mais effectuer un calcul dessus qui prend une valeur par référence (et donc la modifierait).

L’idée de Cow (pour clone-on-write) est de déférer une copie au moment où on en a besoin. Le premier exemple de la doc est relativement parlant. La fonction abs_all modifie potentiellement (mais pas forcément) le vecteur passé en référence pour avoir la valeur absolue élément par élément.

Le code donné en exemple est le suivant :

use std::borrow::Cow;

fn abs_all(input: &mut Cow<[i32]>) {
    for i in 0..input.len() {
        let v = input[i];
        if v < 0 {
            // Clones into a vector if not already owned.
            input.to_mut()[i] = -v;
        }
    }
}

// No clone occurs because `input` doesn't need to be mutated.
let slice = [0, 1, 2];
let mut input = Cow::from(&slice[..]);
abs_all(&mut input);

// Clone occurs because `input` needs to be mutated.
let slice = [-1, 0, 1];
let mut input = Cow::from(&slice[..]);
abs_all(&mut input);

Sans Cow, on pourrait implémenter de la façon suivante :

fn abs_all(input: &mut [i32]) {
    for i in 0..input.len() {
        let v = input[i];
        if v < 0 {
            input[i] = -v;
        }
    }
}

// unnecessary clone!
let slice = [0, 1, 2];
let mut input = slice.clone();
abs_all(&mut input);

// clone would be performed by Cow
let slice = [-1, 0, 1];
let mut input = slice.clone();
abs_all(&mut input);

Mais le problème avec ce deuxième code est que le premier clone ne sert à rien puisque la valeur n’est pas modifiée. On la dédouble donc en mémoire sans raison, ce qui prend du temps et de la place inutiles.

Cow abstrait un besoin d’optimisation de copie : la donnée n’est copiée que si nécessaire. Dans l’exemple donné, on ne voit pas la différence parce que le vecteur est tout petit, mais si ton tableau prend par exemple 1 Go de RAM, éviter une copie inutile devient intéressant.

I don’t mind that you think slowly, but I do mind that you are publishing faster. — W. Pauli

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte