今天在研究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);
}
}