Is there any reason to prefer System.arraycopy() o

2019-01-13 08:23发布

问题:

When copying an entire array, I've often seen people write:

int[] dest = new int[orig.length];
System.arraycopy(orig, 0, dest, 0, orig.length);

But it seems to me there is no reason to favor this over:

int[] dest = orig.clone();

They're both shallow copies anyway. Probably these folks just don't realize that clone exists. So is there any reason not to use clone?

回答1:

  • clone() makes a distinct copy of the first array with its own reference.
  • System.arraycopy() uses JNI (Java Native Interface) to copy an array (or parts of it), so it is blazingly fast, as you can confirm here;
  • clone() creates a new array with the same characteristics as the old array, i.e., same size, same type, and same contents. Refer to here for some examples of clone in action;
  • manual copying is, well, manual copying. There isn't much to say about this method, except that many people have found it to be the most performant.
  • arraynew = arrayold doesn't copy the array; it just points arraynew to the memory address of arrayold or, in other words, you are simply assigning a reference to the old array.


回答2:

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



回答3:

I happened to look at this question when I was pondering on the same doubt. I feel that the arraycopy() is a method to be used when the array is predefined (i.e. memory is already allocated). Thus, the overhead associated with memory allocation is not repeated.

For example, imagine a case when you have defined a large array which is updated periodically. Then using clone() will recreate a array of required size every time the array is copied. However, arraycopy() uses the pre-allocated memory space.

Thus arraycopy() is more efficient in certain scenarios compared to clone(). On the other hand clone() results in a compact code.



回答4:

Just guessing here, but there might be a good reason to use System.arraycopy because different JVM's could conceivably implement them in a way that takes advantage of native abilities of the underlying system for a performance boost.

For example, a JVM implementation could use a native library call like memcpy which could potentially take advantage of some memory controller tricks to perform the action in some incredibly fast and clever way. However, the Object.clone implementation might not be a good candidate for such optimization due to its virtual nature.