98 votes

Pourquoi la boucle sur range () en Python est-elle plus rapide que d'utiliser une boucle while?

L'autre jour, je faisais quelques Python benchmarking et je suis tombé sur quelque chose d'intéressant. Ci-dessous, deux boucles qui font plus ou moins la même chose. Boucle 1 prend environ deux fois plus long que la boucle 2 à exécuter.

Boucle 1:

int i = 0
while i < 100000000:
  i += 1

Boucle 2:

for n in range(0,100000000):
  pass

Pourquoi est-ce la première boucle est beaucoup plus lent? Je sais que c'est un exemple trivial, mais il a éveillé mon intérêt. Est-il quelque chose de spécial à propos de l'éventail() fonction qui le rend plus efficace que l'incrémentation d'une variable de la même façon?

184voto

kcwu Points 2687

voir le désassemblage du code octet python, vous pouvez avoir une idée plus concrète

utiliser la boucle while:

 1           0 LOAD_CONST               0 (0)
            3 STORE_NAME               0 (i)

2           6 SETUP_LOOP              28 (to 37)
      >>    9 LOAD_NAME                0 (i)              # <-
           12 LOAD_CONST               1 (100000000)      # <-
           15 COMPARE_OP               0 (<)              # <-
           18 JUMP_IF_FALSE           14 (to 35)          # <-
           21 POP_TOP                                     # <-

3          22 LOAD_NAME                0 (i)              # <-
           25 LOAD_CONST               2 (1)              # <-
           28 INPLACE_ADD                                 # <-
           29 STORE_NAME               0 (i)              # <-
           32 JUMP_ABSOLUTE            9                  # <-
      >>   35 POP_TOP
           36 POP_BLOCK
 

Le corps de la boucle a 10 op

plage d'utilisation:

 1           0 SETUP_LOOP              23 (to 26)
            3 LOAD_NAME                0 (range)
            6 LOAD_CONST               0 (0)
            9 LOAD_CONST               1 (100000000)
           12 CALL_FUNCTION            2
           15 GET_ITER
      >>   16 FOR_ITER                 6 (to 25)        # <-
           19 STORE_NAME               1 (n)            # <-

2          22 JUMP_ABSOLUTE           16                # <-
      >>   25 POP_BLOCK
      >>   26 LOAD_CONST               2 (None)
           29 RETURN_VALUE
 

Le corps de la boucle a 3 op

Le temps d'exécution du code C est beaucoup plus court que celui d'Intepretor et peut être ignoré.

41voto

Georg Schölly Points 63123

range() est implémenté en C, alors que i += 1 est interprété.

L'utilisation de xrange() pourrait le rendre encore plus rapide pour les grands nombres. Commencer avec Python 3.0 range() est identique à précédemment xrange() .

21voto

Peter Points 48

Il faut dire qu'il y a beaucoup de création et de destruction d'objets en boucle.

 i += 1
 

est le même que:

 i = i + 1
 

Mais comme les in Python sont immuables, cela ne modifie pas l’objet existant; il crée plutôt un nouvel objet avec une nouvelle valeur. C'est fondamentalement:

 i = new int(i + 1)   # Using C++ or Java-ish syntax
 

Le ramasse-miettes aura également une grande quantité de nettoyage à faire. "La création d'objet coûte cher".

4voto

John Montgomery Points 3770

Parce que vous utilisez plus souvent du code écrit en C dans l'interpréteur. C'est-à-dire que i + = 1 est en Python, donc lente (comparativement), alors que range (0, ...) est un appel C, la boucle for s'exécutera principalement en C également.

0voto

ohdeargod Points 175

La plupart des appels de méthode intégrés à Python sont exécutés en tant que code C. Le code à interpréter est beaucoup plus lent. En termes d'efficacité de la mémoire et de rapidité d'exécution, la différence est gigantesque. Les composants internes de Python ont été optimisés à l'extrême et il est préférable de tirer parti de ces optimisations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X