2015-10-02 109 views
8

我寫了下面的代碼來測試它需要多長時間的Java執行從0數到數量龐大的簡單的任務:的Java與int和其他整數類型的行爲

public static void main(String[] args) 
{ 
    for(long k = 0 ; k <= 1000000000000000000L /* 18 zeros */ ; k++) 
     ; 
    System.out.println("Finished"); 
} 

我跑程序,等了幾個小時。等了很長時間之後,除了提及一些計算來估計這個運行時間之外,我沒有其他辦法,並且通過簡單的計算,我確信程序最終可以打印消息需要100多年(取決於CPU) 「完了」!

但是,在嘗試了下面的代碼,看起來花費了與上面的代碼一樣多的時間完成後,我意外地看到「完成」消息在我運行程序後的幾分之一秒內被打印出來!

public static void main(String[] args) 
{ 
    int j; 
    for(int i = 0 ; i <= 1000000000 /* 9 zeros */ ; i++) 
     for(j = 0 ; j <= 1000000000 /* 9 zeros */ ; j++) 
      ; 
    System.out.println("Finished"); 
} 

java的行爲與這兩段代碼有什麼不同? Java的行爲與int數之間必然存在一些差異,而且它的行爲與int之外的整數類型之間必須存在差異。

+0

我希望這兩個循環都可以通過JIT編譯器進行優化。然而,似乎這個長循環並沒有因爲什麼原因而被優化。 – Vulcan

+0

SO中已經有類似的問題,但沒有給出好的答案。 – user3437460

回答

0

其實我覺得這是編譯器的編譯器優化技術。我不認爲它是「Java行爲」,它是我們正在討論的特定Java編譯器的行爲。

Java的自己的行爲是在Java語言規範中指定和for-loop specification並未指明intlong類型變量的優化。

對於目前的「官方」編譯器,它可能會或可能不會進行優化long類型在未來增量的變量。

--------------------------------優化試驗

我跑了以下兩個方案:

計劃1(永遠運行):

public static void main(String[] args) 
    { 
     long counter = 0L; 
     int j; 
     for(int i = 0 ; i <= 1000000000 /* 9 zeros */ ; i++) 
      for(j = 0 ; j <= 1000000000 /* 9 zeros */ ; j++) 
       counter++; 
     System.out.println("Finished" + counter); 
    } 

計劃2(立即完成):

public static void main(String[] args) 
    { 
     long counter = 0L; 
     int j; 
     for(int i = 0 ; i <= 1000000000 /* 9 zeros */ ; i++) 
      for(j = 0 ; j <= 1000000000 /* 9 zeros */ ; j++) 
       counter++; 
     System.out.println("Finished"); 
    } 

因此,這是用於檢測是否有一個編譯器可以在嵌套循環之外進行可見的更改,如果沒有,則基本上會跳過內部循環。

+0

儘管確實優化了循環,但這並不能解釋爲什麼使用long *的循環未被優化。 – Vulcan

+0

@Vulcan我同意它不知道。然而,優化技術是特定於某個版本的編譯器的。它不在Java語言規範中 - 即Java編譯器的實現可隨時更改。 「長」類型的優化可能會或可能不會在未來發生。 –

相關問題