锁定老帖子 主题:一个clone的效率问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-12-15
代码如下: class A implements Cloneable { String abc = "ttttttttttttttttttttttttttttt"; String def = "sssssssssssssssssssssssssssss"; void m1() { System.out.println(abc); } void m2() { System.out.println(def); } public Object clone() { Object obj = null; try { obj = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return obj; } private static A a = new A(); public static A getInstance() { return (A) a.clone(); } } public class CloneTest { public static void main(String[] args) throws Exception { long times = 100000; long time1 = 0; long time2 = 0; time1 = testNew(times); time2 = testClone(times); System.out.println(times + " 次 new() 用时[共,平均]:" + time1 + "," + time1 / times); System.err.println(times + " 次 clone() 用时[共,平均]:" + time2 + "," + time2 / times); } public static long testNew(long times) { long start = System.currentTimeMillis(); for (long i = 0; i < times; i++) { new A(); } long end = System.currentTimeMillis(); return end - start; } public static long testClone(long times) { long start = System.currentTimeMillis(); for (long i = 0; i < times; i++) { A.getInstance(); } long end = System.currentTimeMillis(); return end - start; } } 分别修改main函数中的times的值,运行的结果分别如下; 1000 次 new() 用时[共,平均]:15,0 1000 次 clone() 用时[共,平均]:0,0 10000 次 new() 用时[共,平均]:15,0 10000 次 clone() 用时[共,平均]:16,0 100000 次 new() 用时[共,平均]:15,0 100000 次 clone() 用时[共,平均]:63,0 1000000 次 new() 用时[共,平均]:62,0 1000000 次 clone() 用时[共,平均]:625,0 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-12-15
你加一句system.gc()
以防内存使用优化区别.... jvm 对new有很多变态的优化方式 |
|
返回顶楼 | |
发表时间:2006-12-15
我估计也是垃圾收集引起的差异。
你不妨在创建对象之前,先建立一个大数组,把新对象都依次赋给数组,再比较 |
|
返回顶楼 | |
发表时间:2006-12-15
抛出异常的爱 写道 你加一句system.gc()
以防内存使用优化区别.... jvm 对new有很多变态的优化方式 这样的话,是不是就等于说在正常情况下用new的内存开销比clone大? 如果使用那些优化,clone就没有意义了? |
|
返回顶楼 | |
发表时间:2006-12-15
我想应该不是垃圾收集的问题,垃圾收集应该是内存资源问题,我的程序应该反应的CPU时间问题,而且这么小的对象,百万个应该不会太大影响到内存。试了下System.gc(),没有明显不同;数组赋值的用意我还不太清楚,还望提点
![]() 如果是垃圾收集引起的差异,我想替换着先后运行两种创建对象的方式,以及分别单独运行,应该可以剔除这种差异吧,但我分别试了,结果基本没有太大变化 |
|
返回顶楼 | |
发表时间:2006-12-15
我猜测用数组的意义在于保证这些对象不被回收
楼主现在的代码建立的对象属于用完了就扔,没有保持引用 不过我也弄不清楚保持引用会有什么区别 |
|
返回顶楼 | |
发表时间:2006-12-15
用数组分别保存新建的对象也试过了,百万次运行的结果如下:
1000000 次 new() 用时[共,平均]:953,0 1000000 次 clone() 用时[共,平均]:1907,0 应该不是这个问题 |
|
返回顶楼 | |
发表时间:2006-12-15
deafwolf 写道 抛出异常的爱 写道 你加一句system.gc()
以防内存使用优化区别.... jvm 对new有很多变态的优化方式 这样的话,是不是就等于说在正常情况下用new的内存开销比clone大? 如果使用那些优化,clone就没有意义了? 应该是jvm对new操作的优化造成的结果,但是这个和垃圾收集并没有什么关系,这个操作计算的是创建所用的时间,创建对象之后,这些对象何去何从并不重要。 上面有人说clone没有意义,这也是不对的,clone方法的意义在于得到一摸一样的两个对象,这种需求显然不是很多吧,难道有人做过得到10w个一摸一样的对象这种需求吗,我想jvm设计人员在设计的时候肯定也想到了这一点,显然clone就是用在得到一个或几个一摸一样的对象才有用,如果真是10w个这种需求当然要用new,因为用clone不但效率低,而且代码也会变复杂(看看楼主的代码就知道了),由此可以得出: 1,如果需要少量一摸一样的对象,应该使用clone方法。 2,如果需要大量一摸一样的对象,应该使用new方法,而且可以肯定的是jvm对new操作有相当强度的优化。 楼主把两个针对不同目的的操作(new,clone)放在一起对比的结果也说明了他们确实是针对不同需求的 |
|
返回顶楼 | |
发表时间:2006-12-15
ahuaxuan 写道 deafwolf 写道 抛出异常的爱 写道 你加一句system.gc()
以防内存使用优化区别.... jvm 对new有很多变态的优化方式 这样的话,是不是就等于说在正常情况下用new的内存开销比clone大? 如果使用那些优化,clone就没有意义了? 应该是jvm对new操作的优化造成的结果,但是这个和垃圾收集并没有什么关系,这个操作计算的是创建所用的时间,创建对象之后,这些对象何去何从并不重要。 上面有人说clone没有意义,这也是不对的,clone方法的意义在于得到一摸一样的两个对象,这种需求显然不是很多吧,难道有人做过得到10w个一摸一样的对象这种需求吗,我想jvm设计人员在设计的时候肯定也想到了这一点,显然clone就是用在得到一个或几个一摸一样的对象才有用,如果真是10w个这种需求当然要用new,因为用clone不但效率低,而且代码也会变复杂(看看楼主的代码就知道了),由此可以得出: 1,如果需要少量一摸一样的对象,应该使用clone方法。 2,如果需要大量一摸一样的对象,应该使用new方法,而且可以肯定的是jvm对new操作有相当强度的优化。 楼主把两个针对不同目的的操作(new,clone)放在一起对比的结果也说明了他们确实是针对不同需求的 如果是为了得到一模一样的对象,完全可以用new的方法 class Test{ //property public Test(){} public Test(Test test){ this.XXX=test.getXXX(); //... } //setter&getter } 如果仅仅是获得几个相同的对象,直接用new应该更省事,毕竟就那几个对象,不差这点时间,对吧? |
|
返回顶楼 | |
发表时间:2006-12-15
这样说来,clone并没有效率上的优势,仅仅是在操作上带来方便了?
|
|
返回顶楼 | |