objeto lock inmutable immutable example classes java immutability

lock - synchronized class in java



.clone() o Arrays.copyOf()? (4)

Actualizar usando jmh

Usando jmh , obtengo resultados similares, excepto que el clone parece ser marginalmente mejor.

Publicación original

System.arrayCopy una prueba rápida de rendimiento: clone , System.arrayCopy y Arrays.copyOf tienen un rendimiento muy similar (jdk 1.7.06, servidor vm).

Para detalles (en ms), después de JIT:

clon: 68
arrayCopy: 68
Arrays.copyOf: 68

Código de prueba:

public static void main(String[] args) throws InterruptedException, IOException { int sum = 0; int[] warmup = new int[1]; warmup[0] = 1; for (int i = 0; i < 15000; i++) { // triggers JIT sum += copyClone(warmup); sum += copyArrayCopy(warmup); sum += copyCopyOf(warmup); } int count = 10_000_000; int[] array = new int[count]; for (int i = 0; i < count; i++) { array[i] = i; } // additional warmup for main for (int i = 0; i < 10; i++) { sum += copyArrayCopy(array); } System.gc(); // copyClone long start = System.nanoTime(); for (int i = 0; i < 10; i++) { sum += copyClone(array); } long end = System.nanoTime(); System.out.println("clone: " + (end - start) / 1000000); System.gc(); // copyArrayCopy start = System.nanoTime(); for (int i = 0; i < 10; i++) { sum += copyArrayCopy(array); } end = System.nanoTime(); System.out.println("arrayCopy: " + (end - start) / 1000000); System.gc(); // copyCopyOf start = System.nanoTime(); for (int i = 0; i < 10; i++) { sum += copyCopyOf(array); } end = System.nanoTime(); System.out.println("Arrays.copyOf: " + (end - start) / 1000000); // sum System.out.println(sum); } private static int copyClone(int[] array) { int[] copy = array.clone(); return copy[copy.length - 1]; } private static int copyArrayCopy(int[] array) { int[] copy = new int[array.length]; System.arraycopy(array, 0, copy, 0, array.length); return copy[copy.length - 1]; } private static int copyCopyOf(int[] array) { int[] copy = Arrays.copyOf(array, array.length); return copy[copy.length - 1]; }

En un esfuerzo por reducir la mutabilidad, deberíamos usar

public void setValues(String[] newVals) { this.vals = ( newVals == null ? null : newVals.clone() ); }

o

public void setValues(String[] newVals) { this.vals = ( newVals == null ? null : Arrays.copyOf(newVals, newVals.length) ); }



En términos de mutabilidad, proporcionarán exactamente la misma copia superficial de los datos.


Escribí un programa simple para verificar la diferencia.

public static void main(String[] args) throws IOException, InterruptedException, PrinterException { //Verify array remains immutable. String[] str = {"a","b","c"}; String[] strings = str.clone(); //change returned array strings[2]= "d"; System.out.println(Arrays.toString(str)); System.out.println(Arrays.toString(strings)); String[] stringsCopy = Arrays.copyOf(str, str.length); stringsCopy[2]= "d"; System.out.println(Arrays.toString(str)); System.out.println(Arrays.toString(stringsCopy)); //peformance long before = System.currentTimeMillis(); for(int i=0;i<Integer.MAX_VALUE;i++) { str.clone(); } System.out.println("Time Required for Clone: "+ (System.currentTimeMillis()-before)); //peformance long beforeCopy = System.currentTimeMillis(); for(int i=0;i<Integer.MAX_VALUE;i++) { Arrays.copyOf(str, str.length); } System.out.println("Time Required for Copy of: "+ (System.currentTimeMillis()-beforeCopy)); }

Y produce

[a, b, c] [a, b, d] [a, b, c] [a, b, d] Time Required for Clone: 26288 Time Required for Copy of: 25413

Entonces, si ves en ambos casos String[] es inmutable y el rendimiento es casi el mismo pensamiento Arrays.copyOf () es un poco más rápido en mi máquina.

Actualizar

Cambié el programa para crear una matriz grande [100 cadenas] en lugar de una matriz pequeña.

String[] str = new String[100]; for(int i= 0; i<str.length;i++) { str[i]= Integer.toString(i); }

Y movió la copy of método antes copy of método de clone . Con los resultados a continuación.

Time Required for Copy of: 415095 Time Required for Clone: 428501

Que son más de lo mismo. Please do not ask me to run the test again as it takes a while :(

Actualización 2

Para String array 1000000 y para número de iteraciones 10000

Time Required for Copy of: 32825 Time Required for Clone: 30138

copy of toma más tiempo que clone