====== Différences ====== Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente | |||
|
python:benchmark:loops [2015/03/06 11:55] nliautaud |
python:benchmark:loops [2015/03/06 15:21] (Version actuelle) nliautaud |
||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| ====== Boucles ====== | ====== Boucles ====== | ||
| - | ===== Protocole ===== | + | Dans le monde des boucles, ''while'' a souvent les ors de la vitesse. C'était sans compter Python. |
| - | Boucle while : | + | {{page>info}} |
| - | <Code python> | + | |
| - | i = 0 | + | Pour voir la vitesse que met une boucle à se lancer, on choisit d'abord des petites boucles à dix tours, que l'on lance cent mille fois. |
| - | while i < x: | + | |
| - | something() | + | |
| - | i += 1 | + | |
| - | </Code> | + | |
| - | Boucle for : | ||
| <Code python> | <Code python> | ||
| - | for i in range(x): | + | python -m timeit -n 1 -r 100000 -s "i=0" "while i<10: i+=1" |
| - | something() | + | 1 loops, best of 100000: 0.585 usec per loop |
| - | </Code> | + | |
| + | python -m timeit -n 1 -r 100000 -s "for i in range(10): pass" | ||
| + | 1 loops, best of 100000: 0.585 usec per loop | ||
| - | Boucle for préparée : | + | python -m timeit -n 1 -r 100000 -s "r=range(10)" "for i in r: pass" |
| - | <Code python> | + | 1 loops, best of 100000: 0.292 usec per loop |
| - | rng = range(x) | + | |
| - | for i in rng: | + | |
| - | something() | + | |
| </Code> | </Code> | ||
| - | ===== Résultats ===== | + | <gchart 270x130 hbar center "Boucles à 10 tours"> |
| - | + | while = 585 | |
| - | <gchart 270x130 hbar right "Boucles à 1.000.000 de tours"> | + | for = 585 |
| - | while = 0.6408 | + | for préparée = 292 |
| - | for = 0.6034 | + | |
| - | for préparée = 0.5895 | + | |
| </gchart> | </gchart> | ||
| - | Moyenne de 10 essais sur des boucles à 1.000.000 de tours : | + | Les boucles while et for vont exactement à la même vitesse sauf si, surprise, on extraie la fonction ''range()'' de la boucle for, qui va tout à coup deux fois plus vite. |
| - | - Boucle while : 0.6407999277 | + | <WRAP center tip> |
| - | - Boucle for : 0.6034000397 | + | La boucle while est handicapée par l'opération sur un compteur, qui est **interprétée** par python à chaque tour. La fonction ''range()'' est implémentée directement en C dans l'interpréteur et va donc beaucoup plus vite, à moins que l'on prenne la peine de ne pas l'appeller à chaque tour. |
| - | - Boucle for préparée : 0,5895000458 | + | </WRAP> |
| - | <gchart 270x130 hbar right "Boucles à 10 tours"> | + | Pour comparer leurs vitesse de fonctionnement on fait tourner les boucles dix millions de fois. |
| - | while = 6.115 | + | |
| - | for = 6.264 | + | |
| - | for préparée = 5.651 | + | |
| - | </gchart> | + | |
| - | Moyenne de 1.000.000 d'essais sur des boucles à 10 tours : | + | <Code python> |
| + | python -m timeit -n 1 -r 10 -s "i=0" "while i<10000000: i+=1" | ||
| + | 1 loops, best of 10: 687 msec per loop | ||
| - | - Boucle while : 0.000006115 | + | python -m timeit -n 1 -r 10 -s "r=range(10000000)" "for i in r: pass" |
| - | - Boucle for : 0.000006264 | + | 1 loops, best of 10: 214 msec per loop |
| - | - Boucle for préparée : 0,000005651 | + | |
| - | ===== Conclusion ===== | + | python -m timeit -n 1 -r 10 -s "for i in range(10000000): pass" |
| + | 1 loops, best of 10: 1.2 usec per loop | ||
| + | </Code> | ||
| - | La boucle for devant parcourir une liste d'éléments, l'initialisation de ladite liste lui prend du temps, problème que ne rencontre pas la boucle while. La boucle while est donc plus rapide lorsqu'il faut faire beaucoup de fois peu de tours. | + | <gchart 270x130 hbar center "Boucles à 10.000.000 tours"> |
| + | while = 687000 | ||
| + | for préparée = 214000 | ||
| + | for = 1.2 | ||
| + | </gchart> | ||
| - | Une fois lancée la boucle for se montre par contre bien plus véloce que sa voisine, qui s'encombre à chaque tour de boucle d'une opération sur le compteur. La boucle for est donc plus rapide lorsqu'il faut faire peu de fois beaucoup de tours. | + | La boucle for avec la fonction ''range()'' préparée confirme le résultat précédent et creuse l'écart, en allant trois fois plus vite que la boucle while. Très étonnement, la boucle for traditionnelle retourne des résultats un million de fois plus rapides. |
| - | La boule for "préparée", en n'apellant plus la fonction range() à chaque tour, se montre la plus véloce dans toutes les situations. | + | <WRAP center tip> |
| + | Python optimise drastiquement la forme habituelle à la compilation ? | ||
| + | </WRAP> | ||