Optimisation Vector2 / Vector3 / Matrix

Dans cet article, je vais vous parler de l’optimisation des 3 structures suivantes : Vector2, vector3, Matrix. Pour rappel, ces structures permettent respectivement de représenter un point dans un espace 2D, dans un espace 3D, et d’appliquer des transformations sur des entités dans un espace donné.

Rentrons dans le vif du sujet…

Ceux qui les ont déjà utilisées auront vite remarqué qu’il est possible (entre autre) de les additionner ensemble de plusieurs différentes. Prenons un exemple avec la structure Vector3. Voici comment nous pouvons additionner deux vecteurs ensembles :

Vector2 resultat = v1 + v2;

Vector2 resultat = Vector2.Add(v1, v2);

Vector2.Add(ref v1, ref v2, out resultat);

Ces trois lignes de codes ont exactement le même effet, mathématiquement parlant. Mais là où ça devient intéressant, c’est que les performances diffèrent ! Voici ci-dessous les résultats, en millisecondes, d’une boucle de 1 000 000 itérations de chacune de ces additions (obtenus sur un Core i7 720QM) :

v1 + v2 en 3.23 ms

Vector2.Add(v1, v2) en 8.03 ms

Vector2.Add(ref v1, ref v2, out resultat) en 1.46 ms

On remarque tout de suite la différence avec le passage de paramètres par référence !

Mais pourquoi une telle différence ?

Et bien, c’est simple. Rappelons d’abord les différences entre type référence et type valeur. Pour simplifier, un type valeur est stocké sur la pile, alors qu’un type référence a ses données stockées sur le tas, et la référence vers ses données sur le pile (un peu comme un pointeur). Ce qui veut dire que lorsque l’on passe un type référence en paramètre d’une méthode, seulement sa référence est copié, pas les données, alors qu’un type valeur (int, float, bool, toutes les structures…) est copié sur la pile.

Revenons à nos benchmarks. Dans les deux premiers cas, une copie de chaque vecteur est effectué (c’est à dire une copie de 6 float : 2 * 2 float pour les deux vecteurs d’entrée + 2 floats pour le vecteur de retour), alors que dans le dernier cas, le passage par référence des types valeurs évite la copie de la variable, ce qui économise quelques instructions, et donc améliore les performances.

Note : la méthode Vector2.Add(v1, v2) est plus longue que v1 + v2 car, sur 1 000 000 d’itérations, il faut rajouter le coût des appels de méthodes qui commence à se faire sentir

J’ai aussi essayé avec le type Matrix (16 floats…) et voici les résultats pour 1 000 000 itérations :

m1 + m2 en 36.79 ms

Matrix.Add(m1, m2) en 36.9 ms

Matrix.Add(ref m1, ref m2, out resultat) en 15.24 ms

Les performances sont, dans le pire des cas, plus que multipliées par deux !

Conclusion

Ce qu’il faut retenir de tout ça, c’est qu’il vaut mieux utiliser les méthodes avec passage par référence des type valeurs (et c’est vrai en .Net en général), surtout si vous développez pour la Xbox 360. En revanche, on perd en lisibilité dans notre programme ! Il est plus facile de lire v1 + v2 que Vector3.Add(ref v1, ref v2, out resultat). Mais il faudra choisir entre les deux, suivant vos objectifs. Enfin, je termine avec cette phrase (qui n’est pas de moi hein ^^) mais « Optimisez votre code parce qu’il faut le faire, et non parce que vous pouvez le faire ».

MAJ : Cliquez ici pour accéder au code source de l’article

Publié le 11 août 2011, dans Optimisation, XNA 4.0, et tagué , , , , , . Bookmarquez ce permalien. 5 Commentaires.

  1. Génial je vais tout de suite essayer ca dans mon code, par contre un source accompagnant l’article aurait été super 😛

  2. Voilà voilà 🙂 les sources sont disponibles en téléchargement (fichier BenchVector2Matrix)

  3. 1000 Mercis et excellente journée 😀

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s

%d blogueurs aiment cette page :