高效 System.arraycopy on multidimensional array

2022-09-05 00:13:54

我知道一个常见的性能重构是将简单的's替换为forSystem.arraycopy.

我想问:

  1. system.arraycopy究竟什么时候开始有意义(考虑到它是一个本机方法调用)。抄袭小事说,<32有什么优势吗?

  2. 是我的印象,还是不能简单地(有效地)用数组复制复制这样的循环:

       for (int j = 0; j < 2; ++j) {
           vpr[m][s + j][i] = vr[j];
       }
    

答案 1

使用 System.arraycopy 进行快速深度复制并不困难。下面是一个 2D 数组的示例:

for (int i = 0; i < src.length; i++) {
    System.arraycopy(src[i], 0, dest[i], 0, src[0].length);
}

从快速时序测试来看,使用它来复制1000x1000 2D阵列100次需要40毫秒,而使用更明显的两个循环和分配则需要1740毫秒。


答案 2

与所有性能计时问题一样,您确实需要在期望运行代码的环境中进行基准测试。不同的 JVM 版本和硬件(CPU、内存等)配置可能会有不同的结果。这实际上取决于您的特定性能要求。

但是,在达到这种性能调优水平之前,您应该首先清楚地编写代码并首先使其正确。编译器和JIT将能够使用正常的算法表达式为您进行大量优化,但有时手动优化可能会混淆这些自动优化。在您拥有工作产品后,如果性能不是您想要的,那么请仅对热点进行分析和处理。(尽管有时对于更复杂的代码,您可能需要重构和/或更改逻辑。

在这种情况下,如果您复制整个数组,请使用,因为这是执行此操作的标准方法。编译器现在或将来可能会为此提供额外的优化,因为核心API在很大程度上依赖于此,您可以放心,这是JVM开发人员始终希望以最佳方式运行的东西。System.arraycopy

您将需要运行一些循环,因为只能执行单个数组对象,并且使用Java的多维数组实际上是数组的数组。所以。。。System.arraycopy

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;
}    

或者你可以使用哪些用途和内部的一些反射(所以不如直接使用自己快),但不做深度复制。Arrays.copyOfSystem.arraycopySystem.arraycopy