Java per loop vs. while loop. Differenza di prestazioni?

Supponiamo di avere il seguente codice, ci sono tre cicli per fare qualcosa. Funzionerebbe velocemente se cambio il ciclo più esterno da loop a while? grazie ~~

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]; } } } 

No, cambiare il tipo di loop non avrebbe importanza.

L’unica cosa che può renderlo più veloce sarebbe avere meno nidificazione di loop e loop su valori minori.

L’unica differenza tra un ciclo for e un ciclo while è la syntax per definirli. Non c’è nessuna differenza di prestazioni.

 int i = 0; while (i < 20){ // do stuff i++; } 

Equivale a:

 for (int i = 0; i < 20; i++){ // do Stuff } 

(In realtà, il ciclo for è un po 'meglio perché il i sarà fuori portata dopo il ciclo mentre i rimarrò nel caso del ciclo while .)

Un ciclo for è solo un modo sintatticamente più carino di loop.

Questo tipo di micro-ottimizzazione è inutile.

  • Un ciclo while non sarà più veloce.
  • La struttura del ciclo non è il collo di bottiglia.
  • Ottimizza prima il tuo algoritmo.
  • Meglio ancora, non ottimizzare prima. Ottimizza solo dopo aver scoperto che hai davvero un collo di bottiglia nell’algoritmo che non dipende da I / O.

non puoi ottimizzarlo cambiandolo a while.

puoi semplicemente aumentare la velocità molto molto molto molto poco cambiando la linea

 for (int k = 0; k < length - 1; k++) { 

di

 for (int k = 0; k < lengthMinusOne; k++) { 

dove lengthMinusOne è calcolato prima

questa sottrazione è solo calcolando quasi (200x201 / 2) x (200-1) volte ed è un numero molto piccolo per il computer 🙂

Qualcuno ha suggerito di testare while vs for loop, quindi ho creato un codice per verificare se i loop while o loops erano più veloci; in media, oltre 100.000 test, while ciclo era più veloce ~ 95% delle volte. Potrei averlo codificato in modo errato, sono abbastanza nuovo per la programmazione, anche considerando che se avessi fatto solo 10.000 loop, finirono per essere abbastanza costanti.

modifica Non ho spostato tutti i valori dell’array quando sono andato a testare per ulteriori prove. Risolto il problema in modo che fosse più facile cambiare il numero di prove eseguite.

 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."); } } 

Anche se l’ipotesi che il ciclo while fosse più veloce del ciclo for fosse vera (e non lo è), i cicli che avresti dovuto cambiare / ottimizzare non sarebbero quelli esterni ma quelli interni, perché quelli sono eseguiti più volte .

La differenza tra per e mentre è semantica :

  • In un ciclo while, eseguirai un ciclo finché la condizione è vera, il che può variare molto, perché potresti, nel tuo ciclo, modificare le variabili usando per evirare la condizione while.
  • Di solito, in un ciclo for, si esegue il ciclo N time. Questo N può essere variabile, ma non si sposta fino alla fine del ciclo N, poiché di solito gli sviluppatori non modificano le variabili valutate nella condizione del ciclo.

È un modo per aiutare gli altri a capire il tuo codice. Non sei obbligato a non modificare le variabili del ciclo, ma è una pratica comune (e buona).

ecco un link utile a un articolo sull’argomento

secondo esso, il While and For sono quasi due volte più veloci ma entrambi sono uguali.

MA questo articolo è stato scritto nel 2009 e così l’ho provato sulla mia macchina e qui ci sono i risultati:

  • usando java 1.7: l’Iterator era circa il 20% -30% più veloce di For e While (che erano sempre gli stessi)
  • usando java 1.6: l’Iterator era circa il 5% più veloce di For e While (che erano sempre gli stessi)

quindi immagino che la cosa migliore sia semplicemente cronometrare sulla propria versione e sulla propria macchina e concludere da ciò

No, stai ancora eseguendo lo stesso numero di volte. Non avrebbe importanza.

Guarda il tuo algoritmo! Sai in anticipo quali valori del tuo array vengono aggiunti più di una volta?

Se sai che è ansible ridurre il numero di cicli e ciò si tradurrebbe in prestazioni migliori.

Avrebbe importanza se si utilizza la programmazione multi-thread o multiprocessore. Quindi dipenderà anche da come si assegnano i loop ai vari processori / thread.

Non ci sarebbe alcuna differenza di prestazioni. Provalo!

La JVM e, inoltre, il compilatore, avrebbero trasformato entrambi i loop in qualcosa di simile

  label: ;code inside your for loop. LOOP label 

Qualcuno ha provato in questo modo …

 int i = 20; while (--i > -1){ // do stuff } 

Rispetto a:

 for (int i = 0; i < 20; i++){ // do Stuff } 

Basato su questo: https://jsperf.com/loops-analyze (non creato da me) il ciclo while è del 22% più lento di un ciclo for in generale. Almeno in Javascript lo è.