Вы можете проверить это самостоятельно, но сброс и повторное создание массива примерно одинаковы.
Однако, у него есть два минусы
- это вызывает кэш данных процессора для прокрутки, снижая его эффективность.
- это делает вызывая GC более вероятно, особенно если вы делаете это часто, что делает паузу системы, или замедляет его (если он одновременно)
Я предпочитаю повторно использовать массив, а не потому, что это самый быстрый , но это оказывает наименьшее влияние на остальную часть вашего приложения.
for (int size = 16; size <= 16* 1024; size *= 2) {
int count1 = 0, count1b = 0,count2 = 0;
long total1 = 0, total1b = 0, total2 = 0;
for (long i = 0; i < 10000000000L; i += size) {
long start = System.nanoTime();
long[] longs = new long[size];
if (longs[0] + longs[longs.length - 1] != 0)
throw new AssertionError();
long mid = System.nanoTime();
long time1 = mid - start;
Arrays.fill(longs, 1L);
long time2 = System.nanoTime() - mid;
count1b++;
total1b += time1;
if (time1 < 10e3) {// no GC
total1 += time1;
count1++;
}
if (time2 < 10e3) {// no GC
total2 += time2;
count2++;
}
}
System.out.printf("%s KB took on average of %,d ns to allocate, %,d ns to allocate including GCs and %,d ns to fill%n",
size * 8/1024.0, total1/count1, total1b/count1b, total2/count2);
}
печатает
0.125 KB took on average of 35 ns to allocate, 36 ns to allocate including GCs and 19 ns to fill
0.25 KB took on average of 39 ns to allocate, 40 ns to allocate including GCs and 31 ns to fill
0.5 KB took on average of 56 ns to allocate, 58 ns to allocate including GCs and 55 ns to fill
1.0 KB took on average of 75 ns to allocate, 77 ns to allocate including GCs and 117 ns to fill
2.0 KB took on average of 129 ns to allocate, 134 ns to allocate including GCs and 232 ns to fill
4.0 KB took on average of 242 ns to allocate, 248 ns to allocate including GCs and 368 ns to fill
8.0 KB took on average of 479 ns to allocate, 496 ns to allocate including GCs and 644 ns to fill
16.0 KB took on average of 1,018 ns to allocate, 1,055 ns to allocate including GCs and 1,189 ns to fill
32.0 KB took on average of 2,119 ns to allocate, 2,200 ns to allocate including GCs and 2,625 ns to fill
64.0 KB took on average of 4,419 ns to allocate, 4,604 ns to allocate including GCs and 4,728 ns to fill
128.0 KB took on average of 8,333 ns to allocate, 9,472 ns to allocate including GCs and 8,685 ns to fill
Доказывая только, что трудно предположить, один подход быстрее, чем другие во всех случаях.
Если я изменю long[]
к int[]
я вижу так же
0.125 KB took on average of 35 ns to allocate, 36 ns to allocate including GCs and 16 ns to fill
0.25 KB took on average of 40 ns to allocate, 41 ns to allocate including GCs and 24 ns to fill
0.5 KB took on average of 58 ns to allocate, 60 ns to allocate including GCs and 40 ns to fill
1.0 KB took on average of 86 ns to allocate, 87 ns to allocate including GCs and 94 ns to fill
2.0 KB took on average of 139 ns to allocate, 143 ns to allocate including GCs and 149 ns to fill
4.0 KB took on average of 256 ns to allocate, 262 ns to allocate including GCs and 206 ns to fill
8.0 KB took on average of 472 ns to allocate, 481 ns to allocate including GCs and 317 ns to fill
16.0 KB took on average of 981 ns to allocate, 999 ns to allocate including GCs and 516 ns to fill
32.0 KB took on average of 2,098 ns to allocate, 2,146 ns to allocate including GCs and 1,458 ns to fill
64.0 KB took on average of 4,312 ns to allocate, 4,445 ns to allocate including GCs and 4,028 ns to fill
128.0 KB took on average of 8,497 ns to allocate, 9,072 ns to allocate including GCs and 7,141 ns to fill
IMO скажет, что вы должны позволить GC выполнять свою работу, поэтому лучше создать новый массив байтов. Но если вы действительно хотите убедиться, создайте теплый код для JIT, а затем протестируйте свои теории на разных ОС, например Windows и Linux, с помощью той же машины JVM, то есть HotSpot, используйте профилировщик для измерения результатов (или что-то еще) и получить ваши результаты и свои собственные выводы. –
Я предлагаю вам создать небольшой фрагмент, который проверяет это, и измеряет время для обоих. –
Другим вариантом будет использование 'Arrays.fill', также как FYI. –