tipos - Java para el ciclo frente al ciclo while. Diferencia de rendimiento?
sentencia do while (14)
Supongamos que tengo el siguiente código, hay tres para el bucle para hacer algo. ¿Funcionaría rápido si cambio el bucle más externo por el bucle while? gracias ~~
int length = 200;
int test = 0;
int[] input = new int[10];
for(int i = 1; i <= length; i++) {
for (int j = 0; j <=length - i; j++) {
for (int k = 0; k < length - 1; k++) {
test = test + input[j + k];
}
}
}
¿Alguien lo intentó así ...
int i = 20;
while (--i > -1){
// do stuff
}
Comparado con:
for (int i = 0; i < 20; i++){
// do Stuff
}
Alguien sugirió probar while
vs for
loops, así que creé un código para probar si while loops o for loops eran más rápidos; en promedio, más de 100.000 pruebas, while
ciclo fue más rápido ~ 95% del tiempo. Pude haberlo codificado incorrectamente, soy bastante nuevo en la codificación, y también tengo en cuenta que si solo ejecuté 10.000 bucles terminaron siendo bastante parejos en la duración de la ejecución.
editar No cambié todos los valores de la matriz cuando fui a probar para más pruebas. Se corrigió para que sea más fácil cambiar la cantidad de pruebas que ejecuta.
import java.util.Arrays;
class WhilevsForLoops {
public static void main(String[] args) {
final int trials = 100; //change number of trials
final int trialsrun = trials - 1;
boolean[] fscount = new boolean[trials]; //faster / slower boolean
int p = 0; // while counter variable for for/while timers
while (p <= trialsrun) {
long[] forloop = new long[trials];
long[] whileloop = new long[trials];
long systimeaverage;
long systimenow = System.nanoTime();
long systimethen = System.nanoTime();
System.out.println("For loop time array : ");
for (int counter=0;counter <= trialsrun; counter++) {
systimenow = System.nanoTime();
System.out.print(" #" + counter + " @");
systimethen = System.nanoTime();
systimeaverage = (systimethen - systimenow);
System.out.print( systimeaverage + "ns |");
forloop[counter] = systimeaverage;
}
int count = 0;
System.out.println(" ");
System.out.println("While loop time array: ");
while (count <= trialsrun) {
systimenow = System.nanoTime();
System.out.print(" #" + count + " @");
systimethen = System.nanoTime();
systimeaverage = (systimethen - systimenow);
System.out.print( systimeaverage + "ns |");
whileloop[count] = systimeaverage;
count++;
}
System.out.println("===============================================");
int sum = 0;
for (int i = 0; i <= trialsrun; i++) {
sum += forloop[i];
}
System.out.println("for loop time average: " + (sum / trials) + "ns");
int sum1 = 0;
for (int i = 0; i <= trialsrun; i++) {
sum1 += whileloop[i];
}
System.out.println("while loop time average: " + (sum1 / trials) + "ns");
int longer = 0;
int shorter = 0;
int gap = 0;
sum = sum / trials;
sum1 = sum1 / trials;
if (sum1 > sum) {
longer = sum1;
shorter = sum;
}
else {
longer = sum;
shorter = sum1;
}
String longa;
if (sum1 > sum) {
longa = "~while loop~";
}
else {
longa = "~for loop~";
}
gap = longer - shorter;
System.out.println("The " + longa + " is the slower loop by: " + gap + "ns");
if (sum1 > sum) {
fscount[p] = true; }
else {
fscount[p] = false;
}
p++;
}
int forloopfc=0;
int whileloopfc=0;
System.out.println(Arrays.toString(fscount));
for(int k=0; k <= trialsrun; k++) {
if (fscount[k] == true) {
forloopfc++; }
else {
whileloopfc++;}
}
System.out.println("--------------------------------------------------");
System.out.println("The FOR loop was faster: " + forloopfc + " times.");
System.out.println("The WHILE loop was faster: " + whileloopfc + " times.");
}
}
Basado en esto: https://jsperf.com/loops-analyze (no creado por mí) el ciclo while es un 22% más lento que un ciclo for en general. Al menos en Javascript es.
Este tipo de micro-optimización no tiene sentido.
- Un ciclo while no será más rápido.
- La estructura del bucle no es tu cuello de botella.
- Optimiza tu algoritmo primero.
- Mejor aún, no optimices primero. Solo optimícese después de descubrir que realmente tiene un cuello de botella en su algoritmo que no depende de la E / S.
Incluso si la hipótesis del bucle while fuera más rápida que el bucle for era verdadera (y no lo es), los bucles que había tenido que cambiar / optimizar no serían los externos sino los internos, porque esos se ejecutan más veces .
La diferencia entre for y while es semántica :
- En un ciclo while, se repetirá siempre que la condición sea verdadera, lo que puede variar mucho, porque es posible que, en su bucle, modifique las variables utilizando para evitar la condición while.
- Usualmente, en un bucle for, haces un loop N time. Este N puede ser variable, pero no se mueve hasta el final de su ciclo N, ya que los desarrolladores usualmente no modifican las variables evaluadas en la condición de ciclo.
Es una forma de ayudar a otros a comprender su código. No está obligado a no modificar las variables de bucle, pero es una práctica común (y buena).
Mientras que Loop y For son iguales
Mira tu algoritmo! ¿Sabe de antemano qué valores de su matriz se agregan más de una vez?
Si sabe que podría reducir el número de bucles y eso daría como resultado un mejor rendimiento.
No habría diferencia de rendimiento. ¡Pruébalo!
La JVM y, más adelante, el compilador, convertirían ambos bucles en algo así como
label:
;code inside your for loop.
LOOP label
No, cambiar el tipo de ciclo no importaría.
Lo único que puede hacer que sea más rápido sería tener menos anidamiento de bucles y bucles sobre menos valores.
La única diferencia entre un bucle for
y un bucle while es la sintaxis para definirlos. No hay diferencia de rendimiento en absoluto.
int i = 0;
while (i < 20){
// do stuff
i++;
}
Es lo mismo que:
for (int i = 0; i < 20; i++){
// do Stuff
}
(En realidad, el bucle for es un poco mejor porque estaré fuera del alcance después del bucle, mientras que el i
quedará en el bucle while).
Un bucle for es solo una forma sintácticamente más bonita de bucle.
No, todavía estás repitiendo el mismo número de veces. No importaría en absoluto.
Solo importaría si está usando programación de múltiples hilos o múltiples procesadores. Entonces también dependerá de cómo se asignan los bucles a los diversos procesadores / subprocesos.
aquí hay un link útil a un artículo sobre el tema
según él, el tiempo y el tiempo son casi dos veces más rápidos, pero ambos son iguales.
PERO este artículo fue escrito en 2009 y lo probé en mi máquina y aquí están los resultados:
- usando Java 1.7: el iterador era aproximadamente un 20% -30% más rápido que For y While (que seguían siendo los mismos)
- utilizando Java 1.6: el iterador era aproximadamente un 5% más rápido que For y While (que seguían siendo los mismos)
así que supongo que lo mejor es simplemente cronometrarlo en su propia versión y máquina y concluir de eso
no puedes optimizarlo cambiándolo a while.
puedes incrementar la velocidad muy, muy, muy poco cambiando la línea
for (int k = 0; k < length - 1; k++) {
por
for (int k = 0; k < lengthMinusOne; k++) {
donde longMinusOne se calcula antes
esta resta solo calcula casi (200x201 / 2) x (200-1) veces y es muy poco número para la computadora :)