2014-09-01 88 views
2

大多數表示,原始的對象存儲在堆,但是,我從下面的性能測試不同的結果:對象,堆或棧中的原語?

public class Performance { 

long sum = 0; 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    long startTime = System.currentTimeMillis(); 
    long pSum = 0; 
    for(int i = 0; i < Integer.MAX_VALUE; i++){ 
     pSum += i; 

    } 
    long endTime = System.currentTimeMillis(); 
    System.out.println("time of using primitive:" + Long.toString(endTime - startTime)); 
    System.out.println(pSum); 

    long startTime1 = System.currentTimeMillis(); 
    Long Sum = 0L; 
    for(int i = 0; i < Integer.MAX_VALUE; i++){ 
     Sum += i; 
    } 
    long endTime1 = System.currentTimeMillis(); 
    System.out.println("time of using object:" + Long.toString(endTime1 - startTime1)); 
    System.out.println(Sum); 

    Performance p = new Performance(); 
    long startTime2 = System.currentTimeMillis(); 
    for(int i = 0; i < Integer.MAX_VALUE; i++){ 
     p.sum += i; 
    } 
    long endTime2 = System.currentTimeMillis(); 
    System.out.println("time of using primitive in object:" + Long.toString(endTime2 - startTime2)); 
    System.out.println(p.sum); 
} 

}

結果是這樣的:

time of using primitive:1454 
2305843005992468481 
time of using object:23870 
2305843005992468481 
time of using primitive in object:1529 
2305843005992468481 

我們可以發現在對象中使用基元和使用基元的時間幾乎相同。所以我很困惑,如果對象中的原語存儲在堆中。爲什麼在對象中使用基元和使用基元的時間成本幾乎相同?

+3

google autoboxing,google JIT優化 – 2014-09-01 01:34:28

+1

「原始對象存儲在堆中」是完全正確的:所有*對象*都在堆中,因此它們的內容也是如此。 – EJP 2014-09-01 01:47:41

+1

謹防從微基準中得出太多的推論。 – 2014-09-01 01:52:38

回答

1

當你去

Long sum; 
... 
sum += 1; 

的JVM,理論上,新龍每次分配,導致多頭是不可改變。現在,一個非常聰明的編譯器可以在這裏做一些聰明的事情,但這解釋了爲什麼你的第二個循環的時間更大。它正在分配Integer.MAXINT新的Sum對象。另一個原因自動裝箱技術很棘手。

另外兩個循環不需要分配新對象。一個使用原始int,另一個可以遞增Performance.sum,而不需要每次都分配一個新的性能。如圖所示,訪問堆棧或堆中的原始int應該大致相同。

你的計時與堆與堆棧的訪問速度很少有關,但是與循環中分配大量對象有關。

正如其他人所指出的,微基準可能會引起誤解。