关于System.arraycopy效率的质疑,欢迎大家进来讨论

blazingfire 2008-05-28 11:02:06
最近正在看ThinkInJavaIII,上面说arraycopy用来考贝数组数据会比自己直接写代码快得多。本来我已经默认了这个结果。但是昨天稍微作了一点测试,
本来是想看看到底会快多少,但是发现结果却是直接写代码反而还快一点,不解!
这是测试代码:

public static void main(String[] args) {
// testfill();
int a[] = new int[10];
Arrays.fill(a, 250);

long start, end, times;
times = 10000000;

start = System.currentTimeMillis();
{
int b[] = new int[10];
for (int i = 0; i < times; i++) {
for (int j = 0; j < b.length; j++)
b[j] = a[j];
}
end = System.currentTimeMillis();
System.out.println("Loop directly=" + (end - start));
System.out.println("b[]=" + Arrays2.toString(b));
}

start = System.currentTimeMillis();
{
int b[] = new int[10];
for (int i = 0; i < times; i++) {
System.arraycopy(a, 0, b, 0, b.length);
}
end = System.currentTimeMillis();
System.out.println("System.arraycopy=" + (end - start));
System.out.println("b[]=" + Arrays2.toString(b));
}
}

输出结果为:
Loop directly=515
b[]=[250,250,250,250,250,250,250,250,250,250]
System.arraycopy=610
b[]=[250,250,250,250,250,250,250,250,250,250]

注:Arrays2.toString(b))是把数组串成字符串。另外我的机器配制大概为:
CPU:(Intel Core2 Duo T8100 2.10GHZ)X2
Memory: 2G
...全文
1054 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
blazingfire 2008-05-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jdlsfl 的回复:]
肯定是System.arraycopy效率高,很可能System.arraycopy用的是内存copy
[/Quote]
这种说法不确切的!本人对汇编略知一二,所谓内存Copy其实也是一次次搬运的。

算了结贴了!
  • 打赏
  • 举报
回复
System#arraycopy 是直接对内存中的数据块进行复制的,是一整块一起复制的,它是采用本地编码实现的。

而采用下标一个一个地进行赋值时,时间主要浪费在了寻址和赋值上。

因此,建议复制数组或者动态增加数组长度时,采用 System#arraycopy 方法。

像我们常用的 ArrayList 内部就是采用数组存储的,在满掉的时候,就采用 System#arraycopy 来动态
增加其内部存储容量的。
jdlsfl 2008-05-28
  • 打赏
  • 举报
回复
肯定是System.arraycopy效率高,很可能System.arraycopy用的是内存copy
anqini 2008-05-28
  • 打赏
  • 举报
回复
就比如说,100米比赛,前5米肯定是看不出来谁最快,可能成绩差的人起跑快,但是厉害的人越跑越快,后劲十足!
blazingfire 2008-05-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 anqini 的回复:]
int a[] = new int[10];//改为int a[] = new int[100];之后看看结果~让你满意!
[/Quote]
看来,我是粗心了。已经试过了,当数组的长度越大,测的结果就越让人兴奋。

private static void testArrayCopyRate() {
int size = 1000;
double a[] = new double[size];
Arrays.fill(a, 250);

long start, end, times;
times = 100000;

start = System.currentTimeMillis();
{
double b[] = new double[size];
for (int i = 0; i < times; i++) {
for (int j = 0; j < b.length; j++)
b[j] = a[j];
}
end = System.currentTimeMillis();
System.out.println("Loop directly=" + (end - start));
//System.out.println("b[]=" + Arrays2.toString(b));
}

start = System.currentTimeMillis();
{
double b[] = new double[size];
for (int i = 0; i < times; i++) {
System.arraycopy(a, 0, b, 0, b.length);
}
end = System.currentTimeMillis();
System.out.println("System.arraycopy=" + (end - start));
//System.out.println("b[]=" + Arrays2.toString(b));
}
}

结果:
Loop directly=500
System.arraycopy=47
猜想:
应该是Java在用下标访问的时候,加上了边界检查,呵呵
anqini 2008-05-28
  • 打赏
  • 举报
回复
int a[] = new int[10];//改为int a[] = new int[100];之后看看结果~让你满意!
laorer 2008-05-28
  • 打赏
  • 举报
回复
建议你分两个函数来测试,一个函数测试你的,一个测System.

62,610

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧