2010-01-14 35 views
7

Soy consciente de que una refactorización rendimiento común es reemplazar simples for 's por System.arraycopy.eficiente System.arraycopy en matrices multidimensionales

quiero preguntar acerca de:

  1. Cuando funciona exactamente el sistema. arraycopy comienza a tener sentido (considerando que es una llamada a un método nativo). ¿Copiar cosas pequeñas, por ejemplo, < 32 tiene alguna ventaja?

  2. ¿Es mi impresión, o no es simplemente posible copiar (eficientemente) un ciclo de este tipo con arraycopy:

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

Si está absolutamente loco por el rendimiento, (no debe ser así a menos que haga una evaluación comparativa e identifique un cuello de botella) a menudo puede reemplazar una matriz multidimensional con una matriz unidimensional. –

Respuesta

3

System.arrayCopy es probablemente la forma más rápida de copiar una matriz, pero no hace copias en profundidad.

Tampoco puede hacer el ejemplo más complejo en su segunda pregunta.

1

yo sepa, System.arraycopy es la forma más eficiente y mejor para copiar tus matrices. No conozco ninguna situación en la que la forma alternativa de implementar tus propios bucles sea mucho más eficiente para las copias directas.

7

Como todas las preguntas de tiempo de rendimiento, realmente necesita comparar en el entorno en el que espera ejecutar el código. Las diferentes versiones de JVM y las configuraciones de hardware (CPU, memoria, etc.) pueden tener diferentes resultados. Realmente depende de tus requisitos de rendimiento específicos.

Pero luego, antes de llegar a este nivel de ajuste del rendimiento, primero debe escribir el código claramente y hacerlo bien primero. El compilador y el JIT podrán realizar muchas optimizaciones con expresiones de algoritmos normales, pero a veces las optimizaciones manuales pueden confundir estas optimizaciones automáticas. Después de tener un producto en funcionamiento y si el rendimiento no es el deseado, entonces perfile y trabaje solamente en los puntos calientes. (Aunque a veces para código más complejo puede necesitar refactorizar y/o cambiar su lógica.)

En este caso, si copia matrices completas, utilice System.arraycopy ya que esta es la manera estándar de hacerlo. El compilador puede ahora o en el futuro proporcionar optimizaciones adicionales para eso, ya que las API principales dependen de esto en gran medida, puede estar seguro de que esto es algo que los desarrolladores de JVM siempre desean que funcione de manera óptima.

Necesitará ejecutar algunos bucles, ya que System.arraycopy solo puede hacer un solo objeto de matriz y con matrices multidimensionales de Java son realmente matrices de matrices. Así que ...

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

O usted podría utilizar Arrays.copyOf que utiliza System.arraycopy y una reflexión interna (lo que no es tan rápido como directamente a través de System.arraycopy mismo), pero no hace una copia profunda.

21

No es difícil usar System.arraycopy para hacer una copia rápida y profunda. Este es un ejemplo para una matriz 2D:

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

Desde una prueba de tiempo rápida, usando esto para copiar una matriz 2D 1000x1000 100 veces tarda 40 milisegundos, frente a 1740 milisegundos usando los dos más obvia para los bucles y asignación.

+0

Mi requisito era omitir la primera fila y crear una nueva matriz con el resto de las filas. Entonces, lo modifiqué de la siguiente manera. for (int i = 1; i hemanto

Cuestiones relacionadas