Например:
a) int [x][y][z]
по сравнению с
b) int[x*y*z]
Первоначально мысль я пошел бы с a) для простоты.
Я знаю, что Java не хранит массивы линейно в памяти как C, делает, но какие последствия это имеет для моей программы?
Обычно лучше всего искать ответы на такие вопросы, чтобы увидеть, как варианты компилируются в байт-код 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()
. Вот результаты:
Линейная запись
Линейное чтение
Случайное чтение
Случайное число немного вводит в заблуждение, поскольку оно генерирует 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, смешанный режим)
Используйте первый вариант (3-мерный), потому что его легче понять и меньше шансов сделать какую-то логическую ошибку (особенно если вы используете его для моделирования 3-мерного пространства)