Обычно лучше всего искать ответы на такие вопросы, чтобы увидеть, как варианты компилируются в байт-код JVM:
multi = new int[50][50];
single = new int[2500];
Это переводится на:
BIPUSH 50
BIPUSH 50
MULTIANEWARRAY int[][] 2
ASTORE 1
SIPUSH 2500
NEWARRAY T_INT
ASTORE 2
Итак, как вы можете видеть, JVM уже знает, что мы говорим о многомерном массиве.
Сохраняя его дальше:
for (int i = 0; i < 50; ++i)
for (int j = 0; j < 50; ++j)
{
multi[i][j] = 20;
single[i*50+j] = 20;
}
Это переводится (пропуская циклы) в:
ALOAD 1: multi
ILOAD 3: i
AALOAD
ILOAD 4: j
BIPUSH 20
IASTORE
ALOAD 2: single
ILOAD 3: i
BIPUSH 50
IMUL
ILOAD 4: j
IADD
BIPUSH 20
IASTORE
Итак, как вы можете видеть, многомерный массив обрабатывается внутри виртуальной машины без дополнительных затрат, генерируемых бесполезными инструкциями, в то время как при использовании одной из них используется больше команд, поскольку смещение вычисляется вручную.
Я не думаю, что производительность будет такой проблемой.
РЕДАКТИРОВАТЬ:
Я сделал несколько простых тестов, чтобы увидеть, что здесь происходит,Я решил попробовать разные примеры: линейное чтение, линейная запись и произвольный доступ.Время выражается в миллисекундах (и рассчитывается с использованием System.nanoTime()
. Вот результаты:
Линейная запись
- Размер: 100x100 (10000) Мульти: 5.786591 Один: 6.131748
- Размер: 200x200 (40000) Мульти: 1.216366 Одноместный: 0.782041
- Размер: 500x500 (250000) Мульти: 7.177029 Одноместный: 3.667017
- Размер: 1000x1000 (1000000) Мульти: 30.508131 Одноместный:18.064592
- Размер: 2000x2000 (4000000) Мульти: 185.3548 Одноместный: 155.590313
- Размер: 5000x5000 (25000000) Мульти: 955.5299 Одноместный: 923.264417
- Размер: 10000x10000 (100000000) Мульти: 4084.798753 Одиночный: 4015.448829
Линейное чтение
- Размер: 100x100 (10000) Мульти: 5.241338 Одноместный: 5.135957
- Размер: 200x200 (40000) Мульти: 0.080209 Одноместный: 0.044371
- Размер: 500x500 (250000) Мульти: 0.088742 Одноместный: 0,084476
- Размер: 1000x1000 (1000000) Мульти: 0.232095 Одноместный: 0.167671
- Размер: 2000x2000(4000000) Мульти: 0,481683 Одноместный: 0,33321
- Размер: 5000x5000 (25000000) Multi: 1.222339 Single: 0.828118 Размер: 10000x10000 (100000000) Multi: 2.496302 Single: 1.650691
Случайное чтение
- Размер: 100x100 (10000) Мульти: 22.317393 Одноместный: 8.546134
- Размер: 200x200 (40000) Мульти: 32.287669 Одноместный: 11.022383
- Размер: 500x500 (250000) Мульти: 189.542751 Одноместный: 68.181343
- Размер: 1000x1000 (1000000) Мульти: 1124.78609 Одноместный: 272.235584
- Размер: 2000x2000 (4000000) Мульти: 6814.477101 Одноместный: 1091.998395
- Размер: 5000x5000 (25000000) Мульти: 50051.306239 Одноместный: 7028.422262
Случайное значение немного вводит в заблуждение, поскольку оно генерирует 2 случайных числа для многомерного массива, а одно - для одномерного (и PNRG могут потреблять некоторое количество ресурсов ЦП).
Имейте в виду, что я попытался позволить JIT работать, используя бенчмаркинг только после 20-го запуска того же цикла.Для полноты моей виртуальной машины Java является следующее:
версия Java "1.6.0_17" Java (TM) SE Runtime Environment (сборка 1.6.0_17-b04) Java HotSpot (TM) 64-битная виртуальная машина сервера(сборка 14.3-b01, смешанный режим)