java 多维数组上的高效 System.arraycopy
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2068370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Efficient System.arraycopy on multidimensional arrays
提问by i30817
I'm aware that a common performance refactoring is to replace simple for's by System.arraycopy.
我知道一个常见的性能重构是将 simple 替换for为System.arraycopy.
I want to ask about:
我想问一下:
When exactly does system.arraycopy begin to make sense (considering it's a native method call). Does copying small things say, < 32 have any advantage?
Is it my impression, or is it not simply possible to copy (efficiently) a cycle like this with arraycopy:
for (int j = 0; j < 2; ++j) { vpr[m][s + j][i] = vr[j]; }
system.arraycopy 什么时候开始有意义(考虑到它是一个本地方法调用)。抄小东西说,<32有什么好处吗?
这是我的印象,还是不能简单地使用 arraycopy 复制(有效地)这样的循环:
for (int j = 0; j < 2; ++j) { vpr[m][s + j][i] = vr[j]; }
采纳答案by Thilo
System.arrayCopyis likely the fastest way to copy an array, but it does not make deep copies.
System.arrayCopy可能是复制数组最快的方法,但它不会进行深度复制。
It also cannot do the more complex example in your second question.
它也不能在你的第二个问题中做更复杂的例子。
回答by adammtlx
It's not difficult to use System.arraycopy to do a quick deep copy. Here's an example for a 2D array:
使用 System.arraycopy 进行快速深拷贝并不难。下面是一个二维数组的例子:
for (int i = 0; i < src.length; i++) {
System.arraycopy(src[i], 0, dest[i], 0, src[0].length);
}
From a quick timing test, using this to copy a 1000x1000 2D array 100 times takes 40 milliseconds, versus 1740 milliseconds using the more obvious two for loops and assignment.
从快速计时测试来看,使用它复制 1000x1000 2D 数组 100 次需要 40 毫秒,而使用更明显的两个 for 循环和分配需要 1740 毫秒。
回答by Kevin Brock
Like all performance timing questions, you really need to benchmark in the environment where you are expecting to run your code. Different JVM versions and hardware (CPU, memory, etc) configurations may have different results. It really depends on your specific performance requirements.
与所有性能计时问题一样,您确实需要在期望运行代码的环境中进行基准测试。不同的 JVM 版本和硬件(CPU、内存等)配置可能会有不同的结果。这实际上取决于您的特定性能要求。
But then, before getting to this level of performance tuning, you should first write the code clearly and make it right first. The compiler and JIT will be able to to a lot of optimizations for you with normal algorithm expressions but sometimes hand optimizations can confuse these automated optimizations. After you have a working product and if performance is not then what you would like, then profile and work on the hot spots only. (Though sometimes for more complex code you may need to refactor and/or change your logic.)
但是,在达到这种性能调优水平之前,您应该首先清楚地编写代码并使其正确。编译器和 JIT 将能够使用普通算法表达式为您进行大量优化,但有时手动优化可能会混淆这些自动优化。在您拥有可工作的产品后,如果性能不是您想要的,那么仅在热点上进行分析和工作。(尽管有时对于更复杂的代码,您可能需要重构和/或更改逻辑。)
In this case, if you copying entire arrays then use System.arraycopyas this is the standard way to do that. The compiler may now or in the future provide additional optimizations for that since the core APIs rely on this heavily you can rest assured that this is something that the JVM developers always want to have running optimally.
在这种情况下,如果您复制整个数组,则使用,System.arraycopy因为这是执行此操作的标准方法。编译器现在或将来可能会为此提供额外的优化,因为核心 API 严重依赖于此,您可以放心,这是 JVM 开发人员一直希望以最佳方式运行的东西。
You will need to run through some loops though since System.arraycopycan only do a single array object and with Java multi-dimension arrays are really arrays of arrays. So...
您将需要运行一些循环,因为System.arraycopy只能执行单个数组对象,并且 Java 多维数组实际上是数组数组。所以...
public int[][][] copyOf3Dim(int[][][] array) {
int[][][] copy;
copy = new int[array.length][][];
for (int i = 0; i < array.length; i++) {
copy[i] = new int[array[i].length][];
for (int j = 0; j < array[i].length; j++) {
copy[i][j] = new int[array[i][j].length];
System.arraycopy(array[i][j], 0, copy[i][j], 0,
array[i][j].length);
}
}
return copy;
}
Or you could use Arrays.copyOfwhich uses System.arraycopyand some reflection internally (so is not as fast as directly using System.arraycopyyourself), but does not do a deep copy.
或者你可以在内部使用Arrays.copyOfwhich usesSystem.arraycopy和一些反射(所以不如直接使用System.arraycopy你自己快),但不做深层复制。
回答by Sands
AFAIK, System.arrayCopy is the most efficient and best way to copy your arrays. I am not aware of any situations where the alternate way of implementing your own loops would be much more efficient for direct copies.
AFAIK,System.arrayCopy 是复制数组的最有效和最好的方法。我不知道在任何情况下,实现您自己的循环的替代方法对于直接复制会更有效。
回答by c0der
In my use case this
在我的用例中
public <T> T[][] arrayCopy(T[][] array) {
return Arrays.stream(array).
map(el -> el.clone()).toArray(a -> array.clone());
}
was wayfaster than using System.arraycopyor the straight forward two forloops solution.
Also tested with primitives ( arrayCopy(int[][] array)) and got the same result.
是方法比使用速度System.arraycopy或直线前进2for循环的解决方案。
还用基元 ( arrayCopy(int[][] array))进行了测试并得到了相同的结果。

