Em Java, temos algumas maneiras de fazer cópias ou sub-cópias de arrays:
- Manualmente: criar outro array e copiar elemento a elemento
- Utilizar System.arraycopy
- Utilizar Arrays.copyOfRange ou Arrays.copyOf para versão do Java maior ou igual a 1.6
Qual deles é melhor? Criei um código simples de teste que copia 1 milhão de arrays de int com tamanho de 2048. Para a cópia manual foi utilizado o seguinte código:
for(int idx=0;idx<copied.length;idx++) { copied[idx] = toCopy[idx]; }
Para o System.arraycopy:
System.arraycopy(toCopy,0,copied,0,copied.length);
E para o Arrays.copyOf:
copied = Arrays.copyOf(toCopy, copied.length);
Claro que isso não é um bechmarking muito confiável, mas é só para ter uma noção, logo mais analisaremos a implementação deles. Ao executar os testes na minha máquina a média de execução para as cópias de 1 milhão de arrays na implementação manual foi de 293 millisegundos, para o da classe System, 195 millisegundos e para o da classe Arrays, 1126 millisegundos. Lembrando que não estamos considerando as instanciações dos arrays. Se fizermos isso, o tempo vai ser semelhante para os 3 métodos, já que o tempo de alocação de memória é enormemente maior que o de cópia do array e por esse motivo o Arrays.copyOf demora mais, já que ele faz a instanciação interna conforme veremos posteriormente.
O System.arraycopy utiliza implementação nativa:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
O código em C++ pode ser visto na source do jdk, por ser nativo e ter diretivas de desempenho específicas para esse método, o método utilizando System.arraycopy tende a ser mais eficiente que o método manual.
Para o Arrays.copyOf temos a seguinte implementação:
public static int[] copyOf(int[] original, int newLength) { int[] copy = new int[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
Como podemos ver na linha 2, ele instancia o array, por isso acaba sendo mais lento que os outros no quesito tempo de execução individual do métodos, mas ele utiliza o System.arraycopy para realizar a cópia.
Meu veridito para uso dos métodos de cópias de array é: nunca utilize o método manual se for cópia simples, utilize o System.arraycopy quando você já tiver o objeto de destino da cópia instanciado ou sua versão do Java é inferior a 1.6 e o Arrays.copyOf em todos os outros casos, pois facilita a leitura e é tão performático quanto o System.arraycopy se você considerar o tempo de instanciação (que é feito internamente).
Copiar arrays em Java: Em Java, temos algumas maneiras de fazer cópias ou sub-cópias de arr... https://t.co/Eukb6arqfD (via @thiagovespa)
Muito bom seu site!