Многомерные массивы в Java и C#
В C# есть 2 способа создания многомерных массивов.
int[,] array1 = new int[32,32];
int[][] array2 = new int[32][];
for(int i=0;i<32;i++) array2[i] = new int[32];
Я знаю, что первый метод создает 1-мерный массив внутри, а второй метод создает массив массивов (более медленный доступ).
однако в Java нет такой вещи, как [,], и я вижу многомерные массивы, объявленные так:
int[][] array3 = new int[32][32];
поскольку такой синтаксис запрещен в C#, а Java не имеет int[,]
, мне интересно, равно ли это array1
? Или это все еще массив массивов?
6 ответов
вы ошибаетесь; зубчатые (вложенные) массивы быстрее. (среда CLR оптимизирована для них)
Java не поддерживает истинные многомерные массивы; это массив массивов.
Синтаксис Java автоматически создает все внутренние массивы; в C# для этого потребуется отдельный цикл.
поскольку люди были обеспокоены производительностью многомерных vs шахматных массивов в .NET, я реализовал несколько тестов и сравнил результаты на 8K по 8K элементам:
тесты:
- многомерный 2D массив
- многомерные с индексами назад (y первый)
- многомерное с GetLength (x) вместо целочисленной границы
- пошатываясь, с обратной indicies
- пошатываясь
- одномерный (размер x размер) с умножением в индексе
- одномерный с индексом приращения
результаты:
one <> Elapsed Time: 0.543558s
two <> Elapsed Time: 0.8911516s
three <> Elapsed Time: 0.8908123s
four <> Elapsed Time: 1.1367238s
five <> Elapsed Time: 0.3039648s
six <> Elapsed Time: 0.8110969s
seven <> Elapsed Time: 0.2629394s
для удовольствия я запустил их на эмуляторе WP7, а также получил аналогичные номера.
код тестовой функции здесь.
это все еще массив массивов. Просто в C# вам нужно будет создать каждый поддерево в цикле. Так эта Java:
// Java
int[][] array3 = new int[32][32];
эквивалентно этому C#:
// C#
int[][] array3 = new int[32][];
for (int i = 0; i < array3.Length; i++)
{
array3[i] = new int[32];
}
(Как говорит Slaks, зубчатые массивы обычно быстрее в .NET, чем прямоугольные массивы. Но с точки зрения памяти они менее эффективны.)
в Java вы объявляете массив массивов.
вы можете увидеть это с помощью следующего кода:
int[][] arrOfArr = new int[5][];
arrOfArr[0] = new int[5];
arrOfArr[1] = new int[1];
arrOfArr[2] = new int[9];
...
int[][] arr = new int[3][3];
- это просто сокращенная запись:
int[][] arr = new int[3][];
arr[0] = new int[3];
arr[1] = new int[3];
arr[2] = new int[3];
я переводил некоторый Java-код на C# - вот как я сделал Jagged array
//Java
private static int grad3[][] = {{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},{1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}};
//C#
private static int[,] grad3setup = { { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, { 1, 0, 1 }, { -1, 0, 1 }, { 1, 0, -1 }, { -1, 0, -1 },
{ 0, 1, 1 }, { 0, -1, 1 }, { 0, 1, -1 }, { 0, -1, -1 } };
private static int[][] grad3
{
get
{
int[][] grad3 = new int[12][];
for (int i = 0; i < grad3.Length; i++)
{
grad3[i] = new int[3] { grad3setup[i, 0], grad3setup[i, 1], grad3setup[i, 2] };
}
return grad3;
}
}
это массив массивов с теми же компромиссами производительности, что и в C#. Если вы знаете, что Ваш массив массивов не будет зазубренным, вы можете обернуть его в класс, чтобы получить 2-d индексирование на 1-d резервном массиве.