====== Opérateurs ====== ===== Opérateurs mathématiques ===== Les opérateurs mathématiques en python se comptent au nombre de sept : addition, soustraction, multiplication, division, reste de la division (modulo), division entière et puissance. La logique voudrait que les trois premiers soient très rapides, mais que la division et les autres soient bien plus lents. Jettons-y un oeil, en testant des nombres entiers, des nombres flottants, et les deux mélangés. Lorsque le compilateur est capable de déterminer le résultat à l'avance, par exemple en notant directement ''4 / 4'', le résultat est précalculé à la compilation. La variable ''i'' sert ici à forcer le programme à interpréter l'opération. # nombres entiers python -m timeit -n 1000000 -r 100 -s "i=4" "i + 4" 1000000 loops, best of 100: 0.0327 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i - 4" 1000000 loops, best of 100: 0.0318 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i * 4" 1000000 loops, best of 100: 0.0318 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i / 4" 1000000 loops, best of 100: 0.0381 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i % 4" 1000000 loops, best of 100: 0.0692 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i // 4" 1000000 loops, best of 100: 0.0697 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i ** 4" 1000000 loops, best of 100: 0.291 usec per loop # nombres flottants python -m timeit -n 1000000 -r 100 -s "i=4.0" "i + 4.0" 1000000 loops, best of 100: 0.0335 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4.0" "i - 4.0" 1000000 loops, best of 100: 0.0335 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4.0" "i * 4.0" 1000000 loops, best of 100: 0.0325 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4.0" "i / 4.0" 1000000 loops, best of 100: 0.0335 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4.0" "i % 4.0" 1000000 loops, best of 100: 0.0526 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4.0" "i // 4.0" 1000000 loops, best of 100: 0.112 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4.0" "i ** 4.0" 1000000 loops, best of 100: 0.102 usec per loop # entiers et flottants python -m timeit -n 1000000 -r 100 -s "i=4" "i + 4.0" 1000000 loops, best of 100: 0.0841 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i - 4.0" 1000000 loops, best of 100: 0.0819 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i * 4.0" 1000000 loops, best of 100: 0.0829 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i / 4.0" 1000000 loops, best of 100: 0.0837 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i % 4.0" 1000000 loops, best of 100: 0.106 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i // 4.0" 1000000 loops, best of 100: 0.166 usec per loop python -m timeit -n 1000000 -r 100 -s "i=4" "i ** 4.0" 1000000 loops, best of 100: 0.162 usec per loop addition = 327 soustraction = 318 multiplication = 318 division= 381 reste = 692 div. entière = 697 puissance = 2910 addition = 335 soustraction = 335 multiplication = 325 division = 335 reste = 526 div. entière = 1120 puissance = 1020 addition = 841 soustraction = 819 multiplication = 829 division = 837 reste = 1060 div. entière = 1660 puissance = 1620 Addition, soustraction, multiplication **et division** vont strictement à la même vitesse. Le reste de la division (modulo) est à peine un peu plus lent, et la division entière est pareillement rapide sur des nombres entiers. Lorsqu'il y a des nombres flottants en jeu, la division entière et la puissance sont beaucoup plus longs. Et la puissance de nombres entiers crève littéralement le plafond. Le mélange de types est plus de deux fois plus lent. La vitesse d'exécution des opérateurs arithmétiques de base est entièrement liée aux optimisations que peut faire le compilateur, et, en bout de chaîne, au processeur qui les execute. Dans d'autres contextes (version de python plus ancienne, système différent, etc.), les résultats pourraient être différents et, par exemple, avaliser l'idée que la division soit beaucoup plus lente que la multiplication, mais ce n'est plus le cas lors de mes derniers essais. ====Incrémentation et addition==== python -m timeit -n 1000000 -r 10 -s "i=0" "i = i+1" 1000000 loops, best of 10: 0.0958 usec per loop python -m timeit -n 1000000 -r 10 -s "i=0" "i += 1" 1000000 loops, best of 10: 0.0958 usec per loop addition = 1 incrémentation = 1 Incrémentation et addition sont tout aussi rapides. Python n'a pas de réelle incrémentation comme ''++'' : les nombres en python étant inalterables, le seul moyen de changer la valeur d'une variable est de lui assigner une autre valeur. Il s'agit donc intrinsèquement de la même opération, le ''+='' étant seulement un raccourci de syntaxe. Le compilateur produit le même //bytecode// pour les deux : import dis def add(i): i = i+1 def inc(i): i += 1 dis.dis(add) dis.dis(inc) 2 0 LOAD_FAST 0 (i) 3 LOAD_CONST 1 (1) 6 BINARY_ADD 7 STORE_FAST 0 (i) 10 LOAD_CONST 0 (None) 13 RETURN_VALUE 3 0 LOAD_FAST 0 (i) 3 LOAD_CONST 1 (1) 6 INPLACE_ADD 7 STORE_FAST 0 (i) 10 LOAD_CONST 0 (None) 13 RETURN_VALUE