Maison  >  Article  >  développement back-end  >  Quelle méthode de boucles Python la plus rapide peut bouleverser votre compréhension !

Quelle méthode de boucles Python la plus rapide peut bouleverser votre compréhension !

王林
王林avant
2023-04-17 23:10:011190parcourir

Comme nous le savons tous, Python n’est pas un langage efficace. De plus, le bouclage est une opération très chronophage dans n’importe quelle langue. Si une opération simple en une seule étape prend 1 unité de temps, si cette opération est répétée des dizaines de milliers de fois, le temps final passé augmentera également des dizaines de milliers de fois.

while et for sont deux mots-clés couramment utilisés pour implémenter des boucles en Python. Il existe en fait une lacune dans leur efficacité opérationnelle. Par exemple, le code de test suivant :

import timeit
def while_loop(n=100_000_000) :
 je = 0
 s = 0
 tandis que je <
 s += je
 je += 1
 retour s
def for_loop(n=100_000_000) :
 s = 0
 pour je dans la plage (n):
 s += je
 retour s
def main() :
 print('while looptt', timeit.timeit(while_loop, number=1))
 print('pour looptt', timeit.timeit(for_loop, number=1))
si __name__ == '__main__' :
 principal()
# => boucle while 4.718853999860585
# => boucle for 3.211570399813354

Il s'agit d'une opération de somme simple qui calcule la somme de tous les nombres naturels de 1 à n. Vous pouvez voir que la boucle for est 1,5 seconde plus rapide que la boucle while.

La principale différence réside dans les différents mécanismes entre les deux.

Dans chaque boucle, while effectue en fait deux étapes de plus que for : vérification des limites et incrémentation de la variable i. Autrement dit, chaque fois qu'une boucle est effectuée, while effectuera une vérification des limites (tandis que i < n) et un calcul d'incrément (i +=1). Les deux étapes sont du code Python pur et explicite.

La boucle for n'a pas besoin d'effectuer des opérations de vérification des limites et d'incrémentation, et n'ajoute pas de code Python explicite (le code Python pur est moins efficace que le code C sous-jacent). Lorsque le nombre de cycles est suffisamment important, un écart d’efficacité important apparaît.

Vous pouvez ajouter deux fonctions supplémentaires pour ajouter des vérifications de limites inutiles et incrémenter des calculs dans la boucle for :

importer le temps
def while_loop(n=100_000_000) :
 je = 0
 s = 0
 tandis que je <
 s += je
 je += 1
 retour s
def for_loop(n=100_000_000) :
 s = 0
 pour je dans la plage (n):
 s += je
 retour s
def for_loop_with_inc(n=100_000_000) :
 s = 0
 pour je dans la plage (n):
 s += je
 je += 1
 retour s
def for_loop_with_test(n=100_000_000) :
 s = 0
 pour je dans la plage (n):
 si je <
 passer
 s += je
 retour s
def main() :
 print('while looptt', timeit.timeit(while_loop, number=1))
 print('pour looptt', timeit.timeit(for_loop, number=1))
 print('boucle for avec incrémentt',
 timeit.timeit(for_loop_with_inc, nombre=1))
 print('for boucle avec testtt', timeit.timeit(for_loop_with_test, number=1))
si __name__ == '__main__' :
 principal()
# => boucle while 4.718853999860585
# => pour la boucle 3.211570399813354
# => boucle for avec incrément4.602369500091299
# => boucle for avec test 4.18337869993411

On peut voir que la vérification des limites ajoutée et l'opération d'incrémentation automatique ont en effet grandement affecté l'efficacité d'exécution de la boucle for.

Comme mentionné précédemment, l'interpréteur sous-jacent et les fonctions intégrées de Python sont implémentés en langage C. L'efficacité d'exécution du langage C est bien supérieure à celle de Python.

importer le temps
def while_loop(n=100_000_000) :
 je = 0
 s = 0
 tandis que je <
 s += je
 je += 1
 retour s
def for_loop(n=100_000_000) :
 s = 0
 pour je dans la plage (n):
 s += je
 retour s
def sum_range(n=100_000_000) :
 retourner la somme (plage (n))
def main() :
 print('while looptt', timeit.timeit(while_loop, number=1))
 print('pour looptt', timeit.timeit(for_loop, number=1))
 print('sum rangett', timeit.timeit(sum_range, number=1))
si __name__ == '__main__' :
 principal()
# =>boucle while 4.718853999860585
# => pour la boucle 3.211570399813354
# => sum range0.8658821999561042

On peut voir qu'après avoir utilisé la fonction sum intégrée pour remplacer la boucle, l'efficacité d'exécution du code a augmenté de façon exponentielle.

L'opération d'accumulation de la fonction intégrée sum est en fait une boucle, mais elle est implémentée en langage C, tandis que l'opération de somme dans la boucle for est effectuée par du Python pur. code s += j'ai réalisé. C > Python.

Élargissez votre réflexion. Nous avons tous grandi en entendant des histoires sur l'ingénieux calcul des sommes de 1 à 100 par Gauss.La somme de 1…100 est égale à (1 + 100) * 50. Cette méthode de calcul peut également être appliquée à l'opération de sommation ci-dessus.

importer le temps
def while_loop(n=100_000_000) :
 je = 0
 s = 0
 tandis que je <
 s += je
 je += 1
 retour s
def for_loop(n=100_000_000) :
 s = 0
 pour je dans la plage (n):
 s += je
 retour s
def sum_range(n=100_000_000) :
 retourner la somme (plage (n))
def math_sum(n=100_000_000) :
 retour (n * (n - 1)) // 2
def main() :
 print('while looptt', timeit.timeit(while_loop, number=1))
 print('for looptt', timeit.timeit(for_loop, number=1))
 print('sum rangett', timeit.timeit(sum_range, number=1))
 print('math sumtt', timeit.timeit(math_sum, number=1))
si __name__ == '__main__' :
 principal()
# => boucle while 4.718853999860585
# => pour la boucle 3.211570399813354
# => plage de somme0.8658821999561042
# => somme mathématique 2.400018274784088e-06

Le temps d'exécution final de la somme mathématique est d'environ 2,4e-6, ce qui est raccourci des millions de fois. L’idée ici est que puisque l’efficacité des boucles est faible, un morceau de code doit être exécuté des centaines de millions de fois.

Ne faites simplement pas de boucle et utilisez des formules mathématiques pour transformer des centaines de millions d’opérations de boucle en une seule étape. L’efficacité a naturellement été améliorée comme jamais auparavant.

Conclusion finale (un peu Riddler) :

Le moyen le plus rapide d'implémenter une boucle - - — ——N'utilisez simplement pas de boucles

Pour Python, utilisez autant que possible les fonctions intégrées pour minimiser le code Python pur dans la boucle.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer