¿Qué ciclo es más rápido, mientras o para?

Puede obtener el mismo resultado con los bucles for y while:

Mientras:

$i = 0; while ($i <= 10){ print $i."\n"; $i++; }; 

Por:

 for ($i = 0; $i <= 10; $i++){ print $i."\n"; } 

¿Pero cuál es más rápido?

Eso claramente depende de la implementación particular del intérprete / comstackdor del lenguaje específico.

Dicho esto, teóricamente, cualquier implementación sensata probablemente podrá implementar una en términos de la otra si fuera más rápida, por lo que la diferencia debería ser insignificante como máximo.

Por supuesto, asumí y comporté como en C y en lenguajes similares. Podría crear un lenguaje con semántica completamente diferente para while y for

En C #, el bucle For es ligeramente más rápido.

Para el promedio de bucle alrededor de 2.95 a 3.02 ms.

El ciclo While promedió alrededor de 3.05 a 3.37 ms.

Pequeña aplicación de consola rápida para probar:

  class Program { static void Main(string[] args) { int max = 1000000000; Stopwatch stopWatch = new Stopwatch(); if (args.Length == 1 && args[0].ToString() == "While") { Console.WriteLine("While Loop: "); stopWatch.Start(); WhileLoop(max); stopWatch.Stop(); DisplayElapsedTime(stopWatch.Elapsed); } else { Console.WriteLine("For Loop: "); stopWatch.Start(); ForLoop(max); stopWatch.Stop(); DisplayElapsedTime(stopWatch.Elapsed); } } private static void WhileLoop(int max) { int i = 0; while (i <= max) { //Console.WriteLine(i); i++; }; } private static void ForLoop(int max) { for (int i = 0; i <= max; i++) { //Console.WriteLine(i); } } private static void DisplayElapsedTime(TimeSpan ts) { // Format and display the TimeSpan value. string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine(elapsedTime, "RunTime"); } } 

Encuentro que el ciclo más rápido es un ciclo inverso, por ejemplo:

 var i = myArray.length; while(i--){ // Do something } 

Como han dicho otros, cualquier comstackdor que merezca la pena generará un código prácticamente idéntico. Cualquier diferencia en el rendimiento es insignificante: usted está optimizando en micro.

La verdadera pregunta es, ¿qué es más legible? Y ese es el ciclo for (al menos en mi humilde opinión).

Si ese fuera un progtwig C, yo diría que ninguno. El comstackdor generará exactamente el mismo código. Como no es así, digo medirlo. Realmente, no se trata de qué construcción de bucle es más rápida, ya que es una cantidad minúscula de ahorro de tiempo. Se trata de qué construcción de bucle es más fácil de mantener. En el caso que mostró, un bucle for es más apropiado porque es lo que otros progtwigdores (incluido el futuro, con suerte) esperarán ver allí.

Establezca las iteraciones de bucle en 10,000.

Encuentre el tiempo en milisegundos> Ejecutar bucle> encuentre el tiempo en milisegundos y reste el primer temporizador.

Hazlo para ambos códigos, cualquiera que tenga los milisegundos más bajos se ejecuta más rápido. Es posible que desee ejecutar la prueba varias veces y promediarlas para reducir la probabilidad de que los procesos de fondo influyan en la prueba.

Es probable que obtengas momentos muy similares en ambos, pero estoy interesado en ver si uno siempre es un poco más rápido.

Deberían ser iguales. El bucle for que escribió está haciendo exactamente lo mismo que está haciendo el bucle while: establecer $i=0 , imprimir $i e incrementar $i al final del bucle.

Algunos comstackdores de optimización podrán realizar un mejor despliegue de bucle con un bucle for, pero las probabilidades son que si está haciendo algo que se puede desenrollar, un comstackdor lo suficientemente inteligente como para desenrollarlo también sea lo suficientemente inteligente como para interpretar la condición de bucle de su mientras que el bucle también puede desenrollarse.

Usé un bucle for y while en una máquina de prueba sólida (no se ejecutan procesos de fondo de terceros no estándar). Ejecuté un for loop vs while loop en lo que respecta a cambiar la propiedad de estilo de 10.000 nodos .

La prueba se ejecutó consecutivamente 10 veces, con 1 ejecución agotada por 1500 milisegundos antes de la ejecución:

Aquí está el javascript muy simple que hice para este propósito

 function runPerfTest() { "use strict"; function perfTest(fn, ns) { console.time(ns); fn(); console.timeEnd(ns); } var target = document.getElementsByTagName('button'); function whileDisplayNone() { var x = 0; while (target.length > x) { target[x].style.display = 'none'; x++; } } function forLoopDisplayNone() { for (var i = 0; i < target.length; i++) { target[i].style.display = 'none'; } } function reset() { for (var i = 0; i < target.length; i++) { target[i].style.display = 'inline-block'; } } perfTest(function() { whileDisplayNone(); }, 'whileDisplayNone'); reset(); perfTest(function() { forLoopDisplayNone(); }, 'forLoopDisplayNone'); reset(); }; $(function(){ runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); setTimeout(function(){ console.log('cool run'); runPerfTest(); }, 1500); }); 

Aquí están los resultados que obtuve

 pen.js:8 whileDisplayNone: 36.987ms pen.js:8 forLoopDisplayNone: 20.825ms pen.js:8 whileDisplayNone: 19.072ms pen.js:8 forLoopDisplayNone: 25.701ms pen.js:8 whileDisplayNone: 21.534ms pen.js:8 forLoopDisplayNone: 22.570ms pen.js:8 whileDisplayNone: 16.339ms pen.js:8 forLoopDisplayNone: 21.083ms pen.js:8 whileDisplayNone: 16.971ms pen.js:8 forLoopDisplayNone: 16.394ms pen.js:8 whileDisplayNone: 15.734ms pen.js:8 forLoopDisplayNone: 21.363ms pen.js:8 whileDisplayNone: 18.682ms pen.js:8 forLoopDisplayNone: 18.206ms pen.js:8 whileDisplayNone: 19.371ms pen.js:8 forLoopDisplayNone: 17.401ms pen.js:8 whileDisplayNone: 26.123ms pen.js:8 forLoopDisplayNone: 19.004ms pen.js:61 cool run pen.js:8 whileDisplayNone: 20.315ms pen.js:8 forLoopDisplayNone: 17.462ms 

Aquí está el enlace de demostración

Actualizar

A continuación, se encuentra una prueba separada que he llevado a cabo, que implementa 2 algoritmos factoriales escritos de manera diferente, 1 usando un ciclo for, mientras que el otro usa un ciclo while.

Aquí está el código:

 function runPerfTest() { "use strict"; function perfTest(fn, ns) { console.time(ns); fn(); console.timeEnd(ns); } function whileFactorial(num) { if (num < 0) { return -1; } else if (num === 0) { return 1; } var factl = num; while (num-- > 2) { factl *= num; } return factl; } function forFactorial(num) { var factl = 1; for (var cur = 1; cur <= num; cur++) { factl *= cur; } return factl; } perfTest(function(){ console.log('Result (100000):'+forFactorial(80)); }, 'forFactorial100'); perfTest(function(){ console.log('Result (100000):'+whileFactorial(80)); }, 'whileFactorial100'); }; (function(){ runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); runPerfTest(); console.log('cold run @1500ms timeout:'); setTimeout(runPerfTest, 1500); })(); 

Y los resultados para el benchmark factorial:

 pen.js:41 Result (100000):7.15694570462638e+118 pen.js:8 whileFactorial100: 0.280ms pen.js:38 Result (100000):7.156945704626378e+118 pen.js:8 forFactorial100: 0.241ms pen.js:41 Result (100000):7.15694570462638e+118 pen.js:8 whileFactorial100: 0.254ms pen.js:38 Result (100000):7.156945704626378e+118 pen.js:8 forFactorial100: 0.254ms pen.js:41 Result (100000):7.15694570462638e+118 pen.js:8 whileFactorial100: 0.285ms pen.js:38 Result (100000):7.156945704626378e+118 pen.js:8 forFactorial100: 0.294ms pen.js:41 Result (100000):7.15694570462638e+118 pen.js:8 whileFactorial100: 0.181ms pen.js:38 Result (100000):7.156945704626378e+118 pen.js:8 forFactorial100: 0.172ms pen.js:41 Result (100000):7.15694570462638e+118 pen.js:8 whileFactorial100: 0.195ms pen.js:38 Result (100000):7.156945704626378e+118 pen.js:8 forFactorial100: 0.279ms pen.js:41 Result (100000):7.15694570462638e+118 pen.js:8 whileFactorial100: 0.185ms pen.js:55 cold run @1500ms timeout: pen.js:38 Result (100000):7.156945704626378e+118 pen.js:8 forFactorial100: 0.404ms pen.js:41 Result (100000):7.15694570462638e+118 pen.js:8 whileFactorial100: 0.314ms 

Conclusión: No importa el tamaño de la muestra o el tipo de tarea específico probado, no hay un ganador claro en términos de rendimiento entre un tiempo y para el ciclo. Pruebas realizadas en MacAir con OS X Mavericks en Chrome Evergreen.

Depende del idioma y muy probablemente de su comstackdor, pero deberían ser equivalentes en la mayoría de los idiomas.

No debería importar cuál es más rápido. Si no importa, compárelo con su código real y compruébelo usted mismo.

Las respuestas a esta otra pregunta también podrían ser útiles: Cómo escribir un código más eficiente

Eso dependerá de la implementación del lenguaje de dicho bucle, comstackdor y lo que no.

La mayoría de los comstackdores comstackrán exactamente el mismo código ejecutable, por ejemplo, en CIL (.NET), definitivamente lo hacen.

Fuente: vcsjones @ http://forums.asp.net/t/1041090.aspx

De cualquier manera, el cuerpo del bucle es donde se gastará el tiempo de procesamiento, no la forma en que se itera.

No es un bucle For técnicamente un Do While?

P.ej

 for (int i = 0; i < length; ++i) { //Code Here. } 

sería...

 int i = 0; do { //Code Here. } while (++i < length); 

Aunque podría estar equivocado ...

También cuando se trata de bucles. Si planea solo recuperar datos y nunca modificar los datos, debe usar un foreach. Si necesita los índices reales por algún motivo, deberá boost, por lo que debe usar el ciclo for for normal.

 for (Data d : data) { d.doSomething(); } 

debería ser más rápido que ...

 for (int i = 0; i < data.length; ++i) { data[i].doSomething(); } 

Me preguntaba lo mismo, así que busqué en Google y terminé aquí. Hice una pequeña prueba en python (extremadamente simple) solo para ver y esto es lo que obtuve:

Por:

 def for_func(n = 0): for n in range(500): n = n + 1 

python -m timeit “import for_func; for_func.for_func ()”> for_func.txt

10000 loops, el mejor de 3: 40.5 usec por ciclo

Mientras:

 def while_func(n = 0): while n < 500: n = n + 1 

python -m timeit "import while_func; while_func.while_func ()"> while_func.txt

10000 bucles, el mejor de 3: 45 usec por bucle

En cuanto a los bucles infinitos for(;;) bucle es mejor que while(1) ya que while evalúa cada vez la condición pero de nuevo depende del comstackdor.

También traté de comparar los diferentes tipos de bucle en C #. Usé el mismo código que Shane , pero también probé con un do-while y descubrí que era el más rápido. Este es el código:

 using System; using System.Diagnostics; public class Program { public static void Main() { int max = 9999999; Stopwatch stopWatch = new Stopwatch(); Console.WriteLine("Do While Loop: "); stopWatch.Start(); DoWhileLoop(max); stopWatch.Stop(); DisplayElapsedTime(stopWatch.Elapsed); Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("While Loop: "); stopWatch.Start(); WhileLoop(max); stopWatch.Stop(); DisplayElapsedTime(stopWatch.Elapsed); Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("For Loop: "); stopWatch.Start(); ForLoop(max); stopWatch.Stop(); DisplayElapsedTime(stopWatch.Elapsed); } private static void DoWhileLoop(int max) { int i = 0; do { //Performe Some Operation. By removing Speed increases var j = 10 + 10; j += 25; i++; } while (i <= max); } private static void WhileLoop(int max) { int i = 0; while (i <= max) { //Performe Some Operation. By removing Speed increases var j = 10 + 10; j += 25; i++; }; } private static void ForLoop(int max) { for (int i = 0; i <= max; i++) { //Performe Some Operation. By removing Speed increases var j = 10 + 10; j += 25; } } private static void DisplayElapsedTime(TimeSpan ts) { string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine(elapsedTime, "RunTime"); } } 

y estos son los resultados de una demostración en vivo en DotNetFiddle :

Do While Loop:
00: 00: 00.06

Mientras que Loop:
00: 00: 00.13

En bucle:
00: 00: 00.27