2014-10-02 4 views
0

Когда я запускаю приведенный ниже код, мой вывод блокируется без компиляции или ошибки времени выполнения.Почему объект Integer считается медленнее, чем int в java

Integer count; 
count = Integer.MIN_VALUE; 
while(count != Integer.MAX_VALUE) count++; 
System.out.println("Max Value reached"); 

Я понимаю, что java не поддерживает перегрузку оператора, но не вызывает никакой ошибки почему?

Редактировать: Приведенный выше код действительно работает, но требуется больше времени, поэтому я хочу знать, почему он занимает больше времени?

Я заменил «Integer» на «int», и он быстро возвращается.

+2

Подождите немного. –

+0

Зачем это нужно? 'count ++' работать из-за autoboxing – talex

+0

Отладчик и точка останова быстро убедили бы вас, что он не блокирует и не показал вам, почему, без необходимости в SO-сообщении ... – Tim

ответ

0

Все работает должным образом. Цикл запускает 4,3 миллиарда итераций, поэтому потребуется некоторое время для завершения.

+0

Да, потребовалось больше времени, но когда я меняю 'Integer' на 'int', он возвращается быстро. Извините, я думал, что он блокирует. – Athiruban

+0

@Athiruban Потому что, когда это 'Integer', он также делает неявный бокс, или я предполагаю, что скорее unboxing на каждой итерации цикла. –

+0

@ peter.petrov. Он также будет делать бокс на каждой итерации (и создавать и отбрасывать около 2^32 - 256 объектов в процессе) –

0

Это не блокирование, оно занято. Он еще не достиг System.out.println("Max Value reached");.

Когда вы используете int вместо Integer, это быстрее, так как нет бокса/распаковки. Когда вы используете Integer, он также делает неявный бокс, или я думаю, скорее распаковывается (здесь: count != Integer.MAX_VALUE), на каждой итерации цикла, которая замедляет его.

0

Поскольку есть автобоксинг (и unboxing), вы не писали код с ошибкой. только цикл занимает много времени, чтобы завершить работу. Вы должны подождать еще немного.

Здесь вы можете прочитать об автобоксинге. http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

2

count является Integer. count++ - это эквивалент count = Integer.valueOf(count.intValue() + 1). Медленность обусловлена ​​коробкой/распаковкой.

+0

Я назначил начальное значение счетчику переменных. Итак, теперь у нас есть один объект «count» со своим внутренним значением Integer.MIN_VALUE. В выражении count ++; мы обновляем объект сам по себе, то почему компилятор создает новый объект? Я должен использовать исходный объект только правильно? Я не понимаю, почему он заменен в вышеупомянутой форме, которую вы упомянули. – Athiruban

+1

'Integer' неизменен, как' String', поэтому '++' не может обновить сам объект, больше, чем String-конкатенация изменяет исходную String. '++' может создавать только новый 'Integer' со значением, равным значению, отличному от значения' int' исходного значения Integer. – Tim

1

У вас, похоже, создается впечатление, что int и Integer в основном одинаковы. Далеко от него, но компилятор делает это так, потому что он добавляет все необходимые преобразования за спиной (автоматическое преобразование между примитивными int и оболочкой java.lang.Integer называется autoboxing).

Когда вы писали этот код:

Integer count; 
count = Integer.MIN_VALUE; 
while(count != Integer.MAX_VALUE) count++; 
System.out.println("Max Value reached"); 

Что Javac сделал генерировать для вашего кода является эквивалентом:

Integer count; 
count = Integer.valueOf(Integer.MIN_VALUE); 
while(count.inValue() != Integer.MAX_VALUE) { 
    count = Integer.valueOf(count.intValue() + 1); 
} 
System.out.println("Max Value reached"); 

(я просто явно добавил вызовы компилятор неявно вставляет - с Явы версии ниже 5, вам нужно было бы явно написать его таким образом, потому что в этих версиях не было автобоксинга).

Таким образом, существуют вызовы .intValue() и .valueOf (int). Взгляните на javadocs для .valueOf (int); он создает новый объект Integer для почти каждого вызова. Это означает, что когда вы используете Integer вместо int, в цикле создается около 4 миллиардов объектов, а не просто увеличивается счетчик. Вот почему он занимает больше времени.

+0

Когда я вижу текущий процесс в «Диспетчере задач», используемая память не увеличивается линейно. Итак, что означает, что созданные объекты были мусором, собранным бок о бок? Будет ли он действительно создавать новый объект за итерацию? – Athiruban

+0

@Athiruban Конечно, Integer становится сборщиком мусора, как только новое значение присваивается переменной (на каждой итерации цикла). Вы можете использовать параметры командной строки, чтобы реально увидеть, когда собирает мусор (-verbose: gc) – Durandal

Смежные вопросы