2014-09-19 78 views
2

如果我運行該程序的輸出是:數組初始化 - 性能差異

init: 1239.0 
toCharArray: 1343.6 
arraycopy: 1583.8 

第一個問題是:
爲什麼init()toCharArray()快?這裏有編譯器優化嗎? (我使用Java 1.8.0_20)

第二個問題是:
爲什麼toCharArray()arraycopy()快?我從這裏複製arraycopy()String.toCharArray()

public class MyClass { 

    private static char[] SRC = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; 

    public static void main(String[] args) { 
     long start = 0; 
     int init = 0, toCharArray = 0, arraycopy = 0; 
     for (int j = 0; j < 5; j++) { 
      start = System.currentTimeMillis(); 
      for (int i = 0; i < 100000000; i++) 
       init(); 
      init += (System.currentTimeMillis() - start); 

      start = System.currentTimeMillis(); 
      for (int i = 0; i < 100000000; i++) 
       toCharArray(); 
      toCharArray += (System.currentTimeMillis() - start); 

      start = System.currentTimeMillis(); 
      for (int i = 0; i < 100000000; i++) 
       arraycopy(); 
      arraycopy += (System.currentTimeMillis() - start); 
     } 
     System.out.println("init: " + init/5.0); 
     System.out.println("toCharArray: " + toCharArray/5.0); 
     System.out.println("arraycopy: " + arraycopy/5.0); 
    } 

    private static void init() { 
     char[] c = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; 
     doSomething(c); 
    } 

    private static void toCharArray() { 
     char[] c = "abcdefg".toCharArray(); 
     doSomething(c); 
    } 

    private static void arraycopy() { 
     char[] c = new char[SRC.length]; 
     System.arraycopy(SRC, 0, c, 0, SRC.length); 
     doSomething(c); 
    } 

    private static void doSomething(char[] c) { 
     for (int i = 0; i < c.length; i++) 
      c[i] = ' '; 
    } 

} 

EDIT

卡尺結果:

init:  min=11.90, 1st qu.=12.27, median=12.48, mean=12.44, 3rd qu.=12.54, max=13.16 
toCharArray: min=13.10, 1st qu.=13.21, median=13.39, mean=13.49, 3rd qu.=13.78, max=14.27 
arraycopy: min=15.42, 1st qu.=15.49, median=15.51, mean=15.51, 3rd qu.=15.55, max=15.58 
+6

這些結果可以忽略,因爲你沒有加熱JVM。要麼學習如何微觀Java或使用像Caliper這樣的測試庫。 – 2014-09-19 22:49:45

+0

是的,測試是有缺陷的,如果你切換到CharArray()和arraycopy()我打賭結果會有所不同 – 2014-09-19 23:03:29

+0

我改變了順序:arraycopy:1584.2 toCharArray:1364.0。但是,謝謝你的提示,我會嘗試卡尺! – Krayo 2014-09-19 23:13:34

回答

2

對於"abcdefg".toCharArray()String.toCharArray()source code

public char[] toCharArray() { 
    char result[] = new char[count]; 
    getChars(0, count, result, 0); 
    return result; 
} 

getChars callsSystem.arraycopy因此它的性能與您的arraycopy()應該是一樣的。然而,字符串的從其內部char[]場,getChars副本被聲明爲final

private final char value[]; 

凡從SRCarraycopy()份,其中非最終

private static char[] SRC = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; 

這只是一種猜測,但試圖讓SRC最終並看看會發生什麼。

+0

你是對的!在我完成SRC之後,結果是:toCharArray:1332.2 arraycopy:1322.6。謝謝!所以這裏是優化。你有什麼想法爲什麼'init()'比其他人快一點? – Krayo 2014-09-20 06:48:46

0

我爲我的第一個問題的第一個猜測是以下幾點:

我認爲init()toCharArray()之間的區別在於,用默認值init()跳過數組初始化。但後來我檢查了字節碼,我沒有看到任何區別。

後來我發現this,當我修改我的測試以使用更大的陣列時,我意識到toCharArray()更快!

對於我的第二個問題,我得到了答案(再次感謝)。