2015-10-12 9 views
6
public class Test { 

    public static void main(String[] args) { 

     int x = 150_000; 

     long start = System.currentTimeMillis(); 
     for(int i = 0; i < x; i++) {    
      f1(i); 
     } 
     long end = System.currentTimeMillis(); 
     System.out.println((end - start)/1000.0); 
    } 

    private static long f1(int n) { 
     long x = 1; 
     for(int i = 0; i < n; i++) { 
      x = x + x; 
     } 
     return x; 
    } 
} 

Qualcuno può spiegare perché l'impostazione x per 150_000 o 4_000_000 o addirittura 2_000_000_000 non cambia il tempo di esecuzione di questo ciclo?Perché il tempo di esecuzione del ciclo for non cambia?

+18

Probabilmente il compilatore è abbastanza intelligente da rilevare che non sta accadendo nulla nel ciclo in modo che si ottimizzi. – Tunaki

+0

Come hai valutato? –

+0

@Tunaki Questa sarebbe la mia ipotesi. 'f1' sta restituendo un valore, ma quel valore non è mai usato, e nessun'altra variabile viene modificata durante il metodo. Avrebbe senso (almeno per me) che il compilatore ignori completamente la chiamata. –

risposta

10

Durante l'esecuzione il compilatore JIT (JIT) in JVM compila il bytecode java (formato di classe) nel set di istruzioni nativo della macchina. Il JIT esegue diverse ottimizzazioni durante la compilazione. In questo caso il JIT probabilmente realizzato i seguenti (solo indovinare):

  • il metodo f1() non ha effetti collaterali visibili
  • il valore di ritorno della chiamata f1() non è memorizzato da nessuna parte

pertanto, la JIT ha semplicemente omesso l'invocazione f1() dal codice nativo. È possibile che dopo aver rimosso la chiamata f1() sia stato rimosso anche l'intero ciclo for(int i = 0; i < x; i++) (poiché non cambia anche la semantica del programma).

+0

Adoro il compilatore JIT, anche se a volte, in casi davvero rari, devi renderti conto di ciò che ti aiuta ad ottimizzare il tuo codice. Soprattutto quando si eseguono test delle prestazioni. Bella descrizione +1. –