Overblog Suivre ce blog
Editer l'article Administration Créer mon blog
14 octobre 2010 4 14 /10 /octobre /2010 17:20

Déplacement contre copie

La nouvelle norme du langage C++ introduit une nouveauté de taille, les rvalue references, destinées à réduire le nombre de copies d'objets en privilégiant le déplacement d'un objet plutôt que sa copie lorsque cela est possible. Une rvalue reference est une référence vers un objet anonyme temporaire et s'écrit au moyen de deux symboles & au lieu d'un seul.

En gros, la forme canonique d'une classe T en C++ 11 ressemblera à ça :

 class T
{
int* pi;
public:
T() : pi(new int[100000]) { }
~T() { delete[] pi; }

// Sémantique de copie
T(const T& t) : pi(new int[100000]) { memcpy(pi, t.pi,
100000 * sizeof(int)); }
T& operator=(const T& t) {memcpy(pi, t.pi, 100000 * sizeof(int));}

// Sémantique de déplacement
T(T&& t) : pi(t.pi) {t.pi = nullptr; }
T& operator=(T&& t) {std::swap(pi, t.pi); return *this; }
};

 

Avec en dernier, les deux nouvelles méthodes à implémenter, destinées à être utilisées lorsque l'objet sera déplacé plutôt que copié. On peut noter que le paramètre de ces méthodes n'est pas constant, puisque celui-ci est destiné à être invalidé par le déplacement.

 

Le constructeur de déplacement sera utilisé par le compilateur lorsqu'on affectera un temporaire anonyme, par exemple avec le code suivant :

 

 T creerGrosObjet()
{
T obj1;
return obj1;
}

int main(int argc, char** argv)
{
T obj2 = creerGrosObjet(); // On ne copie pas, on déplace.
return 0;
}

 

 

Dans cet exemple, un compilateur C++ 11 détectera que l'objet affecté à la variable obj2 est un temporaire destiné à être détruit immédiatement et fera donc appel au constructeur de déplacement pour que ob2.pi pointe sur les mêmes données que obj1.pi (qui lui se verra affecter null, sans cela, l'appel au destructeur de obj1 aurait de fâcheuses conséquences).

Comme un petit dessin vaut mieux qu'un long discours, voici une illustration destinée à mettre en évidence la différence entre un déplacement et une copie d'objets.

:

 

  copyvsmove

 

Pour plus d'informations sur les rvalue references, vous pouvez vous référer à http://www.artima.com/cppsource/rvalue.html

Premier benchmark

 

Un premier benchmark de la STL tirant parti de cette optimisation a été posté sur le net et le résultat est plutôt sympathique puisqu'on a presque un facteur 14 de performances entre le test utilisant la copie et celui utilisant le déplacement.

 

http://cpp-next.com/archive/2010/10/howards-stl-move-semantics-benchmark/

 

On peut donc s'attendre à avoir un gain appréciable de performances des programmes C++, dès lors que le commun des mortels aura compris comment les rvalue references fonctionnent.

Car c'est bien là le coeur du problème : les rvalues references viennent complexifier un langage qui n'en avait pas vraiment besoin.

Partager cet article

Repost 0
Published by Olivier - dans Programmation
commenter cet article

commentaires

Présentation

Recherche

Liens