Difference Between the System.Array.Copyto() and System.Array.Clone()

Difference between the System.Array.CopyTo() and System.Array.Clone()

The Clone() method returns a new array (a shallow copy) object containing all the elements in the original array. The CopyTo() method copies the elements into another existing array. Both perform a shallow copy. A shallow copy means the contents (each array element) contains references to the same object as the elements in the original array. A deep copy (which neither of these methods performs) would create a new instance of each element's object, resulting in a different, yet identical object.

So the difference are :

1- CopyTo require to have a destination array when Clone return a new array.
2- CopyTo let you specify an index (if required) to the destination array.
Edit:

Remove the wrong example.

System.Array.CopyTo() and System.Array.Clone()?

When you do B[0] = 9 you are replacing element with 0 index in B array, so A array will stay the same (you don't change it actually) and it doesn't matter which method (CopyTo or Clone) you are using (since A doesn't reference to B).

What is the difference between copying and cloning?

Yes, there is a difference. As far as language dependencies, some languages can do all Shallow, Deep, Lazy copying. Some only do Shallow copies. So yes, it is language dependent sometimes.

Now, take for instance an Array:

int [] numbers = { 2, 3, 4, 5};
int [] numbersCopy = numbers;

The “numbersCopy” array now contains the same values, but more importantly the array object itself points to the same object reference as the “numbers” array.

So if I were to do something like:

  numbersCopy[2] = 0;

What would be the output for the following statements?

  System.out.println(numbers[2]);

System.out.println(numbersCopy[2]);

Considering both arrays point to the same reference we would get:

0

0

But what if we want to make a distinct copy of the first array with its own reference? Well in that case we would want to clone the array. In doing so each array will now have its own object reference. Let’s see how that will work.

  int [] numbers = { 2, 3, 4, 5};

int [] numbersClone = (int[])numbers.clone();

The “numbersClone” array now contains the same values, but in this case the array object itself points a different reference than the “numbers” array.

So if I were to do something like:

  numbersClone[2] = 0;

What would be the output now for the following statements?

  System.out.println(numbers[2]);

System.out.println(numbersClone[2]);

You guessed it:

4

0

Source

Is there any reason to prefer System.arraycopy() over clone()?

No. If you're really microbenchmarking, then maybe, depending on what JVM you're running. But in actuality, no.

Is System.Array.Clone() guaranteed to clone value types?

It works because there's absolutely no way two arrays could share the same instance of a value type.

The spec doesn't specifically say how Array.Clone behaves with value types vs how it behaves with reference types. But the spec does say that instances of value types are copied, bit-by-bit, on assignment. So when array1[i] is copied to array2[i], you get a clone of the instance at index i. Always.

Keep in mind though, that if the value type has a field of a reference type, only the reference will be copied - not the instance of the reference type.

my query was whether potential boxing by Array would negate this. ie the boxed references are copied rather than the underlying value type.

Even if array1[i] was boxed during the cloning, it would have to be unboxed so that you end up with a int[] and not an object[]. The value would be cloned on unboxing.

Why clone() is the best way for copying arrays?

I would like to make some points about why clone() is the fastest way to copy an array than System.arraycopy(..) or others:

1. clone() doesn't have to do the typechecking before copying a source array to the destination one as provided here. It just simple allocates new memory space and assigns the objects to it. On the other hand, System.arraycopy(..) checks for the type and then copies an array.

2. clone() also breaks the optimization to eliminate redundant zeroing. As you know, every allocated array in Java must be initialized with 0s or respective default values. However, JIT can avoid zeroing this array if it sees that the array is filled right after creation. That makes it definitely faster compared to changing the copy values with existing 0s or respective default values. While using System.arraycopy(..) spends significant amount of time clearing and copying the initialized array. To do so I have performed some of the benchmark tests.

@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, batchSize = 1000)
@Measurement(iterations = 10, time = 1, batchSize = 1000)
public class BenchmarkTests {

@Param({"1000","100","10","5", "1"})
private int size;
private int[] original;

@Setup
public void setup() {
original = new int[size];
for (int i = 0; i < size; i++) {
original[i] = i;
}
}

@Benchmark
public int[] SystemArrayCopy() {
final int length = size;
int[] destination = new int[length];
System.arraycopy(original, 0, destination, 0, length);
return destination;
}

@Benchmark
public int[] arrayClone() {
return original.clone();
}

}

Output:

Benchmark                        (size)   Mode  Cnt       Score      Error  Units
ArrayCopy.SystemArrayCopy 1 thrpt 10 26324.251 ± 1532.265 ops/s
ArrayCopy.SystemArrayCopy 5 thrpt 10 26435.562 ± 2537.114 ops/s
ArrayCopy.SystemArrayCopy 10 thrpt 10 27262.200 ± 2145.334 ops/s
ArrayCopy.SystemArrayCopy 100 thrpt 10 10524.117 ± 474.325 ops/s
ArrayCopy.SystemArrayCopy 1000 thrpt 10 984.213 ± 121.934 ops/s
ArrayCopy.arrayClone 1 thrpt 10 55832.672 ± 4521.112 ops/s
ArrayCopy.arrayClone 5 thrpt 10 48174.496 ± 2728.928 ops/s
ArrayCopy.arrayClone 10 thrpt 10 46267.482 ± 4641.747 ops/s
ArrayCopy.arrayClone 100 thrpt 10 19837.480 ± 364.156 ops/s
ArrayCopy.arrayClone 1000 thrpt 10 1841.145 ± 110.322 ops/s

According to the outputs I am getting that clone is almost twice fast from System.arraycopy(..)

3. Also, using manual copying method like clone() results into faster ouput because it doesn't have to make any VM calls (unlike System.arraycopy()).

c# xna how to copy an object array as different array?

If you use CopyTo() c# internally refers to the original array. If you want to create a new instance you have to use Clone().

Example:

object[] src = { "a", "b" };
var dest = src.Clone() as object[];

src[0] = "c";
//// dest still contains "a","b"

Also see: Difference between the System.Array.CopyTo() and System.Array.Clone()

Is it better to use System.arraycopy(...) than a for loop for copying arrays?

public void testHardCopyBytes()
{
byte[] bytes = new byte[0x5000000]; /*~83mb buffer*/
byte[] out = new byte[bytes.length];
for(int i = 0; i < out.length; i++)
{
out[i] = bytes[i];
}
}

public void testArrayCopyBytes()
{
byte[] bytes = new byte[0x5000000]; /*~83mb buffer*/
byte[] out = new byte[bytes.length];
System.arraycopy(bytes, 0, out, 0, out.length);
}

I know JUnit tests aren't really the best for benchmarking, but

testHardCopyBytes took 0.157s to complete

and

testArrayCopyBytes took 0.086s to complete.

I think it depends on the virtual machine, but it looks as if it copies blocks of memory instead of copying single array elements. This would absolutely increase performance.

EDIT:

It looks like System.arraycopy 's performance is all over the place.
When Strings are used instead of bytes, and arrays are small (size 10),
I get these results:

    String HC:  60306 ns
String AC: 4812 ns
byte HC: 4490 ns
byte AC: 9945 ns

Here is what it looks like when arrays are at size 0x1000000. It looks like System.arraycopy definitely wins with larger arrays.

    Strs HC:  51730575 ns
Strs AC: 24033154 ns
Bytes HC: 28521827 ns
Bytes AC: 5264961 ns

How peculiar!

Thanks, Daren, for pointing out that references copy differently. It made this a much more interesting problem!

clone vs copying Array in Java?

The object you created with:

char[] copyThree = new char[7];

will be gc'd. The "final result" could be achieved with:

char[] copyThree = copyFrom.clone();

Using System.arrayCopy, copyFrom and copyTo need to meet certain requirements, like array types and size of the array.

Using the clone method, a new array will be created, with the same contents of the other array (same objects - the same reference, not different objects with same contents). Of course the array type should be the same.

Both ways copy references of the array contents. They not clone the objects:

Object[] array = new Object[] {
new Object(),
new Object(),
new Object(),
new Object()};
Object[] otherArray = new Object[array.length];
Object[] clonedArray = array.clone();

System.arraycopy(array, 0, otherArray, 0, array.length);

for (int ii=0; ii<array.length; ii++) {

System.out.println(array[ii]+" : "+otherArray[ii]+" : "+clonedArray[ii]);

}

Provides:

java.lang.Object@1d256a73 : java.lang.Object@1d256a73 : java.lang.Object@1d256a73
java.lang.Object@36fb2f8 : java.lang.Object@36fb2f8 : java.lang.Object@36fb2f8
java.lang.Object@1a4eb98b : java.lang.Object@1a4eb98b : java.lang.Object@1a4eb98b
java.lang.Object@2677622b : java.lang.Object@2677622b : java.lang.Object@2677622b


Related Topics



Leave a reply



Submit