Creo que la respuesta aquí es un poco más sutil de lo que sugieren las otras respuestas, aunque la esencia es correcta: el ciclo for es más rápido porque ocurren más operaciones en C y menos en Python .
Más específicamente, en el caso del bucle for, suceden dos cosas en C que en el bucle while se manejan en Python:
En el ciclo while, la comparación i < 100000000se ejecuta en Python, mientras que en el ciclo for, el trabajo se pasa al iterador de range(100000000), que internamente realiza la iteración (y, por lo tanto, la verificación de límites) en C.
En el ciclo while, la actualización del ciclo i += 1ocurre en Python, mientras que en el ciclo for nuevamente, el iterador de range(100000000), escrito en C, hace el i+=1(o ++i).
Podemos ver que es una combinación de ambas cosas lo que hace que el bucle for sea más rápido al agregarlos manualmente para ver la diferencia.
import timeit
N = 100000000
def while_loop():
i = 0
while i < N:
i += 1
def for_loop_pure():
for i in range(N):
pass
def for_loop_with_increment():
for i in range(N):
i += 1
def for_loop_with_test():
for i in range(N):
if i < N: pass
def for_loop_with_increment_and_test():
for i in range(N):
if i < N: pass
i += 1
def main():
print('while loop\t\t', timeit.timeit(while_loop, number=1))
print('for pure\t\t', timeit.timeit(for_loop_pure, number=1))
print('for inc\t\t\t', timeit.timeit(for_loop_with_increment, number=1))
print('for test\t\t', timeit.timeit(for_loop_with_test, number=1))
print('for inc+test\t', timeit.timeit(for_loop_with_increment_and_test, number=1))
if __name__ == '__main__':
main()
Probé esto tanto con el número 100000000 como una constante literal como con una variable, Ncomo sería más típico.
while loop 3.5131139
for pure 1.3211338000000001
for inc 3.5477727000000003
for test 2.5209639
for inc+test 4.697028999999999
while loop 4.1298240999999996
for pure 1.3526357999999998
for inc 3.6060175
for test 3.1093069
for inc+test 5.4753364
Como puede ver, en ambos casos, el whiletiempo se acerca mucho a la diferencia de for inc+testy for pure. Tenga en cuenta también que en el caso en que usamos la Nvariable, whiletiene una desaceleración adicional para buscar repetidamente el valor de N, pero forno lo hace.
Es realmente una locura que modificaciones tan triviales puedan resultar en una aceleración de código 3x , pero eso es Python para usted. Y ni siquiera me hagas comenzar cuando puedes usar un builtin sobre un bucle en absoluto ...