Первый фрагмент сразу выбросит NullPointerException: y заполнен null, а присваивание в int требует unboxing. Второй упаковывает нули через cache Integer, третий явно создаёт объекты.
Сравните производительность следующих фрагментов кода, копирующих элементы из массива Integer в массив int и наоборот, включая случай, когда создаются новые объекты Integer из значений int:
Первый фрагмент сразу выбросит NullPointerException: y заполнен null, а присваивание в int требует unboxing. Второй упаковывает нули через cache Integer, третий явно создаёт объекты.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Сравните производительность следующих фрагментов кода, копирующих элементы из массива Integer в массив int и наоборот, включая случай, когда создаются новые объекты Integer из значений int:
int SIZE = 1000000;
int[] x = new int[SIZE];
Integer[] y = new Integer[SIZE];
for (;;) {
for (int i = 0; i < SIZE; ++i) {
x[i] = y[i];
}
}
int SIZE = 1000000;
int[] x = new int[SIZE];
Integer[] y = new Integer[SIZE];
for (;;) {
for (int i = 0; i < SIZE; ++i) {
y[i] = x[i];
}
}
int SIZE = 1000000;
int[] x = new int[SIZE];
Integer[] y = new Integer[SIZE];
for (;;) {
for (int i = 0; i < SIZE; ++i) {
y[i] = new Integer(x[i]);
}
}
Проанализируйте и объясните различия в производительности и поведении между этими подходами.
Ответ
Первый фрагмент сразу выбросит NullPointerException: y заполнен null, а присваивание в int требует unboxing. Второй упаковывает нули через cache Integer, третий явно создаёт объекты.
Во втором случае x изначально содержит нули, поэтому обычное boxing использует Integer.valueOf и кэшируемое значение 0. В третьем new Integer создаёт отдельные экземпляры и увеличивает allocation/GC; этот конструктор deprecated. После инициализации y первый вариант можно сравнивать по unboxing. Бесконечные циклы без корректного benchmark и наблюдаемого результата не дают надёжного рейтинга: JIT может существенно изменить работу.
Источник: docs.oracle.com.