Proglab − Doc

Performance et calcul de puissances

On apprend au collège que x2 = x × x. On pourrait penser que dans un programme, pow(x, 2) (ou x^2 ou l'équivalent selon le langage) c'est « la même chose » que x*x.

En effet ça donne le même résultat. Mais la façon de calculer ce résultat est sensiblement différente.

pow(x, 2) est un appel de fonction, ce qui a en soi un coût en temps d'exécution. De plus la fonction pow exécute un algorithme très général capable aussi de calculer les puissances négatives ou fractionnaires. Le traitement est probablement un peu surdimensionné pour un simple carré.

Au contraire x*x est une simple multiplication, c'est une opération "atomique" hyper spécialisée intégrée directement au microprocesseur.

Dans les navigateurs, en JavaScript

On peut donc s'attendre à une différence de vitesse de calcul en faveur de la multiplication, mais de quel ordre ? Le site jsperf.com permet de publier des tests de vitesse pour comparer les performances d'extraits de code JavaScript sous plusieurs navigateurs. Les tests sont publics, tout le monde peut les effectuer sur sa propre machine, et les résultats cumulés sont affichés.

Au-delà des différences sans grande surprise entre navigateurs, la multiplication est plus rapide. Toujours. Sans ambiguïté. Même pour le cube et la puissance quatrième. En revanche on peut s'étonner que x*x*x*x ne soit pas plus lent que x*x*x.

Les tests détaillés en JavaScript :
Math.pow(x, 2) contre x*x
Math.pow(x, 3) contre x*x*x
Math.pow(x, 4) contre x*x*x*x

Qu'en est-il des autres langages ?

> x = runif(1e8) > print(system.time( x^2 )) utilisateur système écoulé 0.56 0.28 2.37 > print(system.time( x*x )) utilisateur système écoulé 0.44 0.24 0.67
Avec R aussi x*x est plus rapide.

Dans R par exemple, la fonction system.time est prévue pour évaluer le temps d'exécution (en secondes) d'une fonction. La séquence d'instructions ci-contre génère 100 millions de nombres aléatoires (c'est ce qui prend le plus de temps, environ 10s dans ce test), puis mesure le temps pour les élever au carré avec la fonction puissance (x^2) et avec la multiplication x*x.
La différence est encore plus flagrante qu'en javascript : la fonction puissance prend environ 3,5 fois plus de temps que la multiplication.

Cette discussion (en anglais, et sa traduction automatique maladroite en français) évoque le même phénomène en Python et en C.

Conclusion

Pour des calculs isolés, ces différences n'ont aucun impact et sont imperceptibles. Mais certains algorithmes font intervenir un grand nombre d'opérations ou d'itérations. Dans ces cas on pourra observer un gain de vitesse sensible en préférant la multiplication pour calculer les puissances avec de petits exposants entiers.

Licence Creative Commons
Ce texte est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non transposé.
Dernière modification le 18 novembre 2013
commentaires avec Disqus