2014-09-01 6 views
2

Большинство говорит, что примитив объекта хранятся в Heap, однако, я получил разные результаты следующего теста производительности:примитив в объекте, куче или стеке?

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 –

+1

«Примитив в объекте хранится в куче» совершенно правильно: все * объекты * находятся в куче, поэтому их содержимое также. – EJP

+1

Остерегайтесь рисовать слишком много выводов из микро-тестов. –

ответ

1

Когда вы идете

Long sum; 
... 
sum += 1; 

виртуальная машина, в теории, выделяет новый Длинный каждый раз, вызывает Лонгс неизменен. Теперь действительно умный компилятор может сделать что-то умное здесь, но это объясняет, почему ваше время для второго цикла намного больше. Он выделяет объекты Integer.MAXINT new Sum. Еще одна причина Автобоксинга сложна.

Две другие петли не требуют выделения новых объектов. Один использует примитивный int, а в другом вы можете увеличивать Performance.sum без необходимости выделять новое исполнение каждый раз. Доступ к примитиву int в стеке или в куче должен быть примерно одинаково быстрым, как показано.

Ваши тайминги имеют очень мало общего с кучей и скоростью стека доступа, но все, что связано с распределением большого количества объектов в циклах.

Как отмечают другие, микроэлементы могут вводить в заблуждение.