仅复制3D阵列的前2个维度

时间:2022-08-14 04:16:34

I have the following 3D array set up as a buffer between two program states.

我将以下3D数组设置为两个程序状态之间的缓冲区。

private boolean state [][][] = new boolean [20][20][2];

I'm trying to copy everything from

我正在尝试复制一切

state[0-19][0-19][1]

to

state[0-19][0-19][0]

At the moment I'm using a for loop, which works fine, but I can't help feeling that there's a better way. I know I could just use two separate 2D arrays and do a simple copy, but I'm interested to see if there's any way around this.

目前我正在使用for循环,这很好,但我不禁觉得有更好的方法。我知道我可以使用两个单独的2D数组并做一个简单的复制,但我很想知道是否有任何解决方法。

Current loop:

电流回路:

for (int i=0;i<20;i++){
        for (int j=0;j<20;j++){
            state[i][j][0]=state[i][j][1];
    }
}

2 个解决方案

#1


2  

Sometimes you can replace the inner loop with System.arraycopy, which will then be faster. But not in your memory layout, I believe.

有时您可以使用System.arraycopy替换内部循环,这样会更快。但我相信,不是你的记忆布局。

If possible, instead of copying the array, consider updating the references. Recall that "multidimensional" arrays in java are actually arrays of arrays.

如果可能,请考虑更新引用,而不是复制数组。回想一下,java中的“多维”数组实际上是数组的数组。

In particular,

尤其是,

 boolean[] tmp = multi[0];
 multi[0] = multi[1];
 multi[1] = tmp;

swaps the two array references at next-to-zero cost. This is much faster than copying, and then overwriting the old values. But sometimes you need a copy (if you don't overwrite the old values), then you can't do this.

以接近零的成本交换两个数组引用。这比复制要快得多,然后覆盖旧值。但有时你需要一个副本(如果你不覆盖旧的值),那么你不能这样做。

Note that you shouldn't do this blindly:

请注意,您不应盲目地这样做:

 multi[0][0] = 1;
 multi[1] = multi[0];
 multi[1][0] = 0;
 System.err.println(multi[0][0]);

will print 0, because now multi[0] and multi[1] point to the same nested array, and you should have used.

将打印0,因为现在多[0]和多[1]指向相同的嵌套数组,你应该使用。

 multi[1] = multi[0].clone();

Note that also cloning is not deep, so multi.clone() will point to the same nested arrays as multi. There is no built-in deep clone or deep arraycopy in Java, you need to use a loop for that either way.

请注意,克隆也不深,因此multi.clone()将指向与multi相同的嵌套数组。 Java中没有内置的深度克隆或深度数组,你需要使用循环。

But again, none of these supposedly work if you want to copy the second element to the first in lots of arrays. This is a problem of your memory layout.

但是,如果你想将第二个元素复制到许多数组中的第一个元素,那么这些都不会起作用。这是您的内存布局问题。

Recall what your data structure looks like in memory:

回想一下你的数据结构在内存中的样子:

 boolean[][][] -> boolean[][] -> boolean[]{ 0, 1 }
              \               \> boolean[]{ 0, 1 }
               \> boolean[][] -> boolean[]{ 0, 1 }
                              \> boolean[]{ 0, 1 }

you want to copy one element in each array. They can be all across your memory (every boolean[]... is an object of its own!), so there is no way to speed this up with primitives - the data is scattered. Maybe consider changing your memory layout, if possible.

你想复制每个数组中的一个元素。它们可以遍布你的内存(每个boolean [] ...都是它自己的一个对象!),所以没有办法用原语来加速它 - 数据是分散的。如果可能的话,也许可以考虑更改内存布局。

Also consider alternatives to boolean arrays. Booleans take 1 byte of memory, but store only one bit (note that this can be faster, so it's not bad per se!). But sometimes it makes sense to instead store the whole boolean array in a BitSet or a long, and then work with actual bit operations. But gain, sometimes it does pay, sometimes it hurts.

还要考虑布尔数组的替代方法。布尔值占用1个字节的内存,但只存储一位(请注意,这可能更快,因此本身也不错!)。但有时将整个布尔数组存储在BitSet或long中是有意义的,然后使用实际的位操作。但是,获得,有时它确实付出,有时它会伤害。

#2


0  

I like nhahtdh's solution of reorganising the dimensions, but beware that if you copy the reference, then if you later change state[0], state[1] will reflect the change, and vice versa (which, mind you, may actually be what you want). The reference will be accessible in 2 places but store contents in only one place - old pointer/reference confusion. Unit tests are your friend :-)

我喜欢nhahtdh重新组织维度的解决方案,但要注意如果你复制了引用,那么如果你以后改变状态[0],状态[1]将反映变化,反之亦然(请注意,实际上可能是什么你要)。该引用将在2个位置访问,但仅在一个地方存储内容 - 旧指针/参考混淆。单元测试是你的朋友:-)

If you have a single dimension array, the Arrays.copyOf() method can help to avoid some looping code. But remember that a copy of some sometype[] object will copy the reference to the object, not all the individual sometype objects.

如果你有一个单维数组,Arrays.copyOf()方法可以帮助避免一些循环代码。但请记住,某些sometype []对象的副本将复制对象的引用,而不是所有单独的某些类型对象。

You could of course start playing around with .clone() or even Serialization to get "deep" copies of a sometype[] object, but then that gets more complicated than your nested loops quickly.

你当然可以开始使用.clone()甚至序列化来获取sometype []对象的“深层”副本,但是这会比你的嵌套循环快得多。

#1


2  

Sometimes you can replace the inner loop with System.arraycopy, which will then be faster. But not in your memory layout, I believe.

有时您可以使用System.arraycopy替换内部循环,这样会更快。但我相信,不是你的记忆布局。

If possible, instead of copying the array, consider updating the references. Recall that "multidimensional" arrays in java are actually arrays of arrays.

如果可能,请考虑更新引用,而不是复制数组。回想一下,java中的“多维”数组实际上是数组的数组。

In particular,

尤其是,

 boolean[] tmp = multi[0];
 multi[0] = multi[1];
 multi[1] = tmp;

swaps the two array references at next-to-zero cost. This is much faster than copying, and then overwriting the old values. But sometimes you need a copy (if you don't overwrite the old values), then you can't do this.

以接近零的成本交换两个数组引用。这比复制要快得多,然后覆盖旧值。但有时你需要一个副本(如果你不覆盖旧的值),那么你不能这样做。

Note that you shouldn't do this blindly:

请注意,您不应盲目地这样做:

 multi[0][0] = 1;
 multi[1] = multi[0];
 multi[1][0] = 0;
 System.err.println(multi[0][0]);

will print 0, because now multi[0] and multi[1] point to the same nested array, and you should have used.

将打印0,因为现在多[0]和多[1]指向相同的嵌套数组,你应该使用。

 multi[1] = multi[0].clone();

Note that also cloning is not deep, so multi.clone() will point to the same nested arrays as multi. There is no built-in deep clone or deep arraycopy in Java, you need to use a loop for that either way.

请注意,克隆也不深,因此multi.clone()将指向与multi相同的嵌套数组。 Java中没有内置的深度克隆或深度数组,你需要使用循环。

But again, none of these supposedly work if you want to copy the second element to the first in lots of arrays. This is a problem of your memory layout.

但是,如果你想将第二个元素复制到许多数组中的第一个元素,那么这些都不会起作用。这是您的内存布局问题。

Recall what your data structure looks like in memory:

回想一下你的数据结构在内存中的样子:

 boolean[][][] -> boolean[][] -> boolean[]{ 0, 1 }
              \               \> boolean[]{ 0, 1 }
               \> boolean[][] -> boolean[]{ 0, 1 }
                              \> boolean[]{ 0, 1 }

you want to copy one element in each array. They can be all across your memory (every boolean[]... is an object of its own!), so there is no way to speed this up with primitives - the data is scattered. Maybe consider changing your memory layout, if possible.

你想复制每个数组中的一个元素。它们可以遍布你的内存(每个boolean [] ...都是它自己的一个对象!),所以没有办法用原语来加速它 - 数据是分散的。如果可能的话,也许可以考虑更改内存布局。

Also consider alternatives to boolean arrays. Booleans take 1 byte of memory, but store only one bit (note that this can be faster, so it's not bad per se!). But sometimes it makes sense to instead store the whole boolean array in a BitSet or a long, and then work with actual bit operations. But gain, sometimes it does pay, sometimes it hurts.

还要考虑布尔数组的替代方法。布尔值占用1个字节的内存,但只存储一位(请注意,这可能更快,因此本身也不错!)。但有时将整个布尔数组存储在BitSet或long中是有意义的,然后使用实际的位操作。但是,获得,有时它确实付出,有时它会伤害。

#2


0  

I like nhahtdh's solution of reorganising the dimensions, but beware that if you copy the reference, then if you later change state[0], state[1] will reflect the change, and vice versa (which, mind you, may actually be what you want). The reference will be accessible in 2 places but store contents in only one place - old pointer/reference confusion. Unit tests are your friend :-)

我喜欢nhahtdh重新组织维度的解决方案,但要注意如果你复制了引用,那么如果你以后改变状态[0],状态[1]将反映变化,反之亦然(请注意,实际上可能是什么你要)。该引用将在2个位置访问,但仅在一个地方存储内容 - 旧指针/参考混淆。单元测试是你的朋友:-)

If you have a single dimension array, the Arrays.copyOf() method can help to avoid some looping code. But remember that a copy of some sometype[] object will copy the reference to the object, not all the individual sometype objects.

如果你有一个单维数组,Arrays.copyOf()方法可以帮助避免一些循环代码。但请记住,某些sometype []对象的副本将复制对象的引用,而不是所有单独的某些类型对象。

You could of course start playing around with .clone() or even Serialization to get "deep" copies of a sometype[] object, but then that gets more complicated than your nested loops quickly.

你当然可以开始使用.clone()甚至序列化来获取sometype []对象的“深层”副本,但是这会比你的嵌套循环快得多。