2013-07-20 75 views
3

看一看this question沒有JIT優化

代碼:

class test 
{ 
    public static void main(String abc[]) 
    { 
     for(int k=1; k<=3; k++) 
     { 
      for(int N=1; N<=1_000_000_000; N=N*10) 
      { 
       long t1 = System.nanoTime(); 

       int j=1; 
       for(int i=0; i<=N; i++) 
        j=j*i; 

       long t2 = System.nanoTime() - t1; 
       System.out.println("Time taken for "+ N + " : "+ t2); 
      } 
     } 
    } 
} 

以上代碼的輸出:

Time taken for 1 : 2160 
Time taken for 10 : 1142 
Time taken for 100 : 2651 
Time taken for 1000 : 19453 
Time taken for 10000 : 407754 
Time taken for 100000 : 4648124 
Time taken for 1000000 : 12859417 
Time taken for 10000000 : 13706643 
Time taken for 100000000 : 136928177 
Time taken for 1000000000 : 1368847843 
Time taken for 1 : 264 
Time taken for 10 : 233 
Time taken for 100 : 332 
Time taken for 1000 : 1562 
Time taken for 10000 : 17341 
Time taken for 100000 : 136869 
Time taken for 1000000 : 1366934 
Time taken for 10000000 : 13689017 
Time taken for 100000000 : 136887869 
Time taken for 1000000000 : 1368178175 
Time taken for 1 : 231 
Time taken for 10 : 242 
Time taken for 100 : 328 
Time taken for 1000 : 1551 
Time taken for 10000 : 13854 
Time taken for 100000 : 136850 
Time taken for 1000000 : 1366919 
Time taken for 10000000 : 13692465 
Time taken for 100000000 : 136833634 
Time taken for 1000000000 : 1368862705 

在循環中,即使價值我從0開始,表示產品爲零,沒有JIT優化。爲什麼不 ? 在上面提供的鏈接中,我以前將for循環放在JIT正在優化的方法調用中。是否將這些陳述放在優化過程中的方法中?

+0

這並不覺得自己是一個很現實的問題。你正在做一些無用的事情 - JIT優化對真正的*代碼代碼真的很重要嗎? –

+0

您正在測量的時間以納秒爲單位,因此速度足夠快。在這裏查看修改後的測試的毫秒數 - http://ideone.com/Xq0xj1 –

回答

5
  1. 在你前面的問題的JIT優化掉的方法start的完整代碼沒有任何分析,以什麼號碼正好是存在於在方法的返回變量。這是因爲你選擇了使你的方法void,給JIT一個簡單的線索,任何計算的值都將被丟棄。

  2. 將您當前的示例與上一個問題的示例進行對比,沒有void方法調用,所以自然不會發生優化。爲什麼沒有一些其他的優化,這將有助於這個完全不同的情況是一個無法回答的問題。在spencefic JVM實現中沒有這樣的優化,以及您測試代碼的特定JVM調用。

2

環路本身不會獲取即時編譯(由第二和第三執行的略低運行時間所觀察到的),然而消除整個迴路是 - AFAIK - 只有當該方法本身執行多次完成,因爲只有那時JIT纔有足夠的運行時信息來確保它實際上可以消除它而沒有後果。

如果我改變你的代碼,循環被消除在第三次調用:

public class LoopJit2 { 

    public static void main(String abc[]) { 
     for (int x = 0; x < 3; x++) { 
      loopMethod(); 
     } 
    } 

    private static void loopMethod() { 
     for (int N = 1; N <= 1_000_000_000; N = N * 10) { 
      long t1 = System.nanoTime(); 

      int j = 1; 
      for (int i = 0; i <= N; i++) 
       j = j * i; 

      long t2 = System.nanoTime() - t1; 
      System.out.println("Time taken for " + N + " : " + t2); 
     } 
    } 
} 

時間序列:

Time taken for 1 : 1466 
Time taken for 10 : 1467 
Time taken for 100 : 2934 
Time taken for 1000 : 20044 
Time taken for 10000 : 201422 
Time taken for 100000 : 1993200 
Time taken for 1000000 : 4038223 
Time taken for 10000000 : 11182357 
Time taken for 100000000 : 111290192 
Time taken for 1000000000 : 1038002176 
Time taken for 1 : 1466 
Time taken for 10 : 1467 
Time taken for 100 : 2934 
Time taken for 1000 : 20044 
Time taken for 10000 : 10755 
Time taken for 100000 : 124667 
Time taken for 1000000 : 1010045 
Time taken for 10000000 : 10201156 
Time taken for 100000000 : 103184413 
Time taken for 1000000000 : 1019723107 
Time taken for 1 : 978 
Time taken for 10 : 1467 
Time taken for 100 : 1467 
Time taken for 1000 : 1955 
Time taken for 10000 : 978 
Time taken for 100000 : 489 
Time taken for 1000000 : 977 
Time taken for 10000000 : 977 
Time taken for 100000000 : 978 
Time taken for 1000000000 : 978 
+0

根據您的結果,看起來即使原始代碼應該已經通過堆棧替換進行了優化。也許它只需要更長的時間? –

+0

@MarkoTopolnik我也嘗試了更大的迭代次數的原始代碼,我的猜測是它首先需要運行+ jit整個方法至少一次,只有這樣才能得出結論:優化它是安全的。 –

+3

我認爲以每個方法爲基礎實現JIT編譯器/優化器比在方法內的任意塊中嘗試這樣做更可行。所以這似乎也是一個論點,你應該嘗試將功能分解成更小的方法,然後通過其他方法調用。它允許JIT獨立地優化每一個。 –