|
锁定老贴子 主题:一个clone的效率问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2006-12-15
看来些clone的介绍,都说clone比new要效率高,但做了试验,好像结果并不完全验证这个,尤其是运行次数越大的时候,不知道是不是代码什么地方有问题,希望!
代码如下: 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 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间: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并没有效率上的优势,仅仅是在操作上带来方便了?
|
|
| 返回顶楼 | |










