I came across an article by Naresha Joshi about copying and cloning and was surprised by the performance situation. Cloning has problems with the final fields . And given the fact that the Cloneable interface does not provide a clone
method, to call clone
you will need to know the specific type of class.
You can write this code:
((Cloneable)o).clone(); //
If the Cloneable
interface is broken, then the cloning mechanism may have some advantages. When copying memory, it may be more efficient than copying the field behind the field. This is emphasized by Josh Bloch, author of Effective Java:
Doug Lee went even further. He told me that he now clones only when copying arrays. You should use cloning to copy arrays, because in general this is the fastest way. But Doug types no longer implement Cloneable
. He tied him up. And I do not think this is unfounded.
But it was in 2002, didn’t the situation change? Since Java 6, we have Arrays.copyOf
, what about it? What is the performance of copying an object?
There is only one way to find out: get rid of benchmarks.
[UPD] Andrei Paguin pointed out in the comments that there is a problem with the benchmark.
replace “size” with “original.length” in the benchmark Arrays.copyOf ().
And then I realized that yes ... this explains why jit can understand that we are copying exactly the same length. Therefore, I changed the conclusions and article
Let's quickly look at clone
and Arrays.copyOf
as applied to arrays.
The benchmark int array
looks like this:
@Benchmark @CompilerControl(CompilerControl.Mode.DONT_INLINE) public int[] testCopy() { return Arrays.copyOf(original, original.length); // size } @Benchmark @CompilerControl(CompilerControl.Mode.DONT_INLINE) public int[] testClone() { return original.clone(); }
We created an array of random numeric values, then executed clone
or Arrays.copyOf
. Please note: we have returned the copy result to ensure that the code will be executed. In the chapter on escape analysis, we will see how non-returning an array can radically affect the benchmark.
Along with int array
there is a version for byte array
, long array
and Object array
. I use the DONT_INLINE
flag to make it easier to analyze the generated asm if necessary.
mvn clean install java -jar target/benchmark.jar -bm avgt -tu ns -rf csv
Now let's look at the cloning of objects with 4, 8, 16 and 32 fields. Benchmarks are looking for objects with 4 fields :
Source: https://habr.com/ru/post/334176/
All Articles