Автобокс использует Integer.valueOf
, который внутренне кэширует целочисленные объекты для маленьких целых чисел (по умолчанию от -128 до 127, но максимальное значение можно настроить с помощью свойства "java.lang.Integer.IntegerCache.high" - см. Источник код Integer.valueOf), поэтому он отличается от вызова new Integer
напрямую. Поскольку Integer.valueOf
быстро проверяет величину целочисленного значения перед вызовом new Integer
, немного быстрее вызывать new Integer
напрямую (хотя он использует больше памяти, если у вас много маленьких целых чисел). Распределение в Java очень быстрое, и время выполнения GC пропорционально количеству живых короткоживущих объектов (т.е. не пропорционально количеству мусора), поэтому GC также очень быстр.
Но в зависимости от версии JVM и от того, какие оптимизации включены, существует скалярная оптимизация замещения, которая может привести к гораздо большей разнице в производительности при распределении недолговечных объектов (в вашем примере, что оптимизация не может быть выполнена, потому что Вы храните объекты на карте, но во многих других ситуациях это полезно).
В последних версиях JVM существует скалярная замена оптимизация (за исключением 1.6.0_18, где аварийный анализ временно отключен ), что означает, что распределение недолговечных объектов может быть оптимизировано далеко. Когда скалярная замена в JVM была новой, кто-то сделал эталоном , где был код, похожий на ваш. В результате код, использующий примитивы, был самым быстрым, код с явными вызовами new Integer()
был почти таким же быстрым, как и код, использующий примитивы, а код, использующий автобокс, был намного медленнее. Это произошло потому, что в автобоксировании используется Integer.valueOf
, и, по крайней мере, тогда оптимизация скалярной замены не учитывала этот особый случай. Я не знаю, была ли оптимизация улучшена с тех пор.