在Java中高效实现多维数组?

rip*_*234 6 java arrays multidimensional-array

据我理解(从答案如),Java没有天然多维连续存储器阵列(不同于C#,例如).

虽然锯齿状数组语法(数组数组)可能对大多数应用程序都有好处,但我仍然想知道如果你想要连续内存数组的原始效率(避免不必要的内存读取),最佳做法是什么

我当然可以使用映射到2D的单维数组,但我更喜欢更结构化的东西.

irr*_*ble 5

手动操作并不困难:

int[] matrix = new int[ROWS * COLS];

int x_i_j = matrix[ i*COLS + j ];
Run Code Online (Sandbox Code Playgroud)

现在,它真的比java的多维数组快吗?

int x_i_j = matrix[i][j];
Run Code Online (Sandbox Code Playgroud)

对于随机访问,也许.对于连续访问,可能不是 - matrix[i]几乎可以肯定在L1缓存中,如果不在寄存器缓存中.在最佳方案中,matrix[i][j]需要一次添加和一次内存读取; 虽然matrix[i*COLS + j]可能需要2次添加,一次乘法,一次内存读取.但谁在数呢?


Edw*_*uck 3

如果您确实想要具有连续内存数组的更多结构,请将其包装在一个对象中。

public class My2dArray<T> {

  int sizeX;

  private T[] items;

  public My2dArray(int x, int y) {
    sizeX = x;
    items = new T[x*y];
  }

  public T elementAt(int x, int y) {
    return items[x+y*sizeX];
  }

}
Run Code Online (Sandbox Code Playgroud)

这不是一个完美的解决方案,您可能已经知道了。因此,请考虑一下您所怀疑的事实的确认。

Java 仅提供某些用于组织代码的构造,因此最终您将不得不使用类或接口。由于这也需要具体的操作,所以需要一个类。

性能影响包括为每个数组访问创建一个 JVM 堆栈框架,最好避免这种情况;然而,JVM 堆栈框架是JVM 实现其作用域的方式。代码组织需要适当的范围,因此实际上没有办法解决我可以想象的性能损失(在不违反“一切都是对象”的精神的情况下)。

  • 您还可以概括并删除“2D”,并将维度作为构造函数的 var-arg 参数(并让 `elementAt` 采用 var-arg 作为索引) (2认同)