今天在研究Jlibrtp代码时,偶然注意到里面大量使用了System.arraycopy()这个方法,心想既然是协议实现,那用的方法肯定都是效率最高或较高的了,以前对这个System.arraycopy()仅有个抽象的认识。另外,JDK中对ArrayList的add与remove方法的实现,居然也是用的System.arraycopy(),让我不由得对其产生“敬意啊”。今天就来动手试一下到底谁的效率高,到底有多高。
C程序员们经常讨论数组复制的效率,此类笔试面试题也层出不穷。在Java中,数组拷贝可以用:1)for循环;2)clone方法;3)System.arraycopy()。测试如下:
(1)使用了一个70元素的字符串数组;
(2)每种方法各循环拷贝N次。
统计结果如下:
|
重复1000次 |
10万 |
100万 |
500万 |
for循环 |
0 |
47 |
484 |
2421 |
clone方法 |
0 |
32 |
250 |
1235 |
System.arraycopy |
0 |
16 |
94 |
437 |
很明显了,for循环最慢,约为clone方法的2倍,约为System.arraycopy的4~5倍;System.arraycopy最快。
PS:System.arraycopy是调用的JNI,怪不得。
附测试代码:
package copytest; public class ArrayCopyTest { private static String [] src = {"Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff", "Aaaaaaaaaa", "Vvvvvvv", "Bbbb", "Cccc", "Dddd", "Eddeee", "FFFFFFffffffff"}; private static String [] dst; /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(forCopy(5000000)); System.out.println(cloneCopy(5000000)); System.out.println(systemJNICopy(5000000)); } /** * 使用for来复制数组 * @param time 循环执行的次数 * @return 执行的总时间 */ public static long forCopy(int time) { long start = System.currentTimeMillis(); while(time-- > 0) { int size = src.length; dst = new String [size]; for (int i = 0; i < size; i++) { dst[i] = src[i]; } } long end = System.currentTimeMillis(); return (end - start); } public static long cloneCopy(int time) { long start = System.currentTimeMillis(); while(time-- > 0) { dst = (String[])src.clone(); } long end = System.currentTimeMillis(); return (end - start); } public static long systemJNICopy(int time) { long start = System.currentTimeMillis(); while(time-- > 0) { int size = src.length; System.arraycopy(src, 0, dst, 0, size); } long end = System.currentTimeMillis(); return (end - start); } }