我正在使用坐标系x(宽度),y(高度),z(深度)
只是为了清除混淆,如果有任何x& y是一个平面,我使用Z作为高程。
我将每秒访问数组数百万次,并且基准测试显示使用索引的一维数组更快,我想尽可能多地提高效率,以便其他东西可以使用那个时间
例如2D阵列 - > 1D数组创建只是
Object[] oneDArray = new Object[width * height]
并索引数组我可以使用以下内容。
Object obj = oneDArray[x + y * width]
我确实在stackoverflow上找到了以下内容,但我不完全确定哪一个是正确的 How to "flatten" or "index" 3D-array in 1D array?
“正确”答案表示索引数组请执行以下操作
Object[] oneDArray = new Object[width * height * depth]
Object obj = oneDArray[x + WIDTH * (y + DEPTH * z)]
然后另一个答案说“正确”答案是错误的,并使用以下
Object[] oneDArray = new Object[width * height * depth]
Object obj = oneDArray[x + HEIGHT* (y + WIDTH* z)]
读取扁平3D阵列的正确方法是什么?
答案 0 :(得分:6)
这取决于您想要如何在一维数组中订购3D数据, 如果你想按顺序排列索引:Z,Y,X那么你的2x2x2尺寸的3D数据将被存储如下:
index 0: [z=0,y=0,x=0]
index 1: [z=0,y=0,x=1]
index 2: [z=0,y=1,x=0]
index 3: [z=0,y=1,x=1]
index 4: [z=1,y=0,x=0]
index 5: [z=1,y=0,x=1]
index 6: [z=1,y=1,x=0]
index 7: [z=1,y=1,x=1]
DEPTH维度对应z
,高度对应y
,WIDTH对应x
指数计算将为:index = HEIGHT*WIDTH*z + WIDTH*y + x
。
x不会乘以任何东西,因为下一个x索引就在前一个索引之后。
如果要跳过一个Y行,则必须添加整行WIDTH,在本例中为2,例如,如果您在索引1处,其中z = 0,y = 0且x = 1并且您添加索引WIDTH = 2,你将获得索引3.只有y维度增加了1。
要从z = 0移动到z = 1,您必须跳过4个索引(查看索引列表),数字是HEIGHT * WIDTH(在此示例中为2 * 2)。
<强>性能强>
为了获得速度,最好处理您的3D数据,z,y,x坐标按顺序递增,这样您就不必经常重新计算索引。例如:
int z = 1, y=1, x=0;
int index = HEIGHT*WIDTH*z + WIDTH*y;
int data;
for(x=0;x<WIDTH;x++)
{
Object obj = oneDArray[index+x];
}
在理想情况下,所有数据处理都是相互独立的,您甚至不必计算索引,只需通过整个oneDArray
递增一个索引。预计算的可能性取决于您的使用情况。
答案 1 :(得分:0)
使用公式index = x*height*depth + y*depth + z
示例java代码插图。
public class FlattenedArray {
public static void main(String[] args) {
int width = 2;
int height = 3;
int depth = 4;
int[][][] d3 = new int[width][height][depth];
int[] d1 = new int[width*height*depth];
//3D Array :
int w=0;
for(int i=0;i<width;i++)
for(int j=0;j<height;j++)
for(int k=0;k<depth;k++) {
d3[i][j][k] = ++w;
System.out.print(d3[i][j][k] + " ");
}
System.out.println();
//1D Array :
w=0;
for(int i=0;i<width;i++)
for(int j=0;j<height;j++)
for(int k=0;k<depth;k++) {
int index = i*height*depth + j*depth + k;
d1[index] = ++w;
}
for(int i=0;i<width*height*depth;i++) {
System.out.print(d1[i] + " ");
}
}
}
答案 2 :(得分:0)
这是Java中的一个解决方案,可以为您提供:
我自己的微基准测试显示,1D阵列获取/设定值比通过3D阵列快50%。
下面是我选择遍历3D矩阵的路径的图解说明,单元格按其遍历顺序编号:
转换功能:
public int to1D( int x, int y, int z ) {
return (z * xMax * yMax) + (y * xMax) + x;
}
public int[] to3D( int idx ) {
final int z = idx / (xMax * yMax);
idx -= (z * xMax * yMax);
final int y = idx / xMax;
final int x = idx % xMax;
return new int[]{ x, y, z };
}
上面的代码肯定会被分解为更快,但我这样做是为了让它更容易理解2路转换;)