论坛首页 Java企业应用论坛

一个clone的效率问题

浏览 11820 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-12-15  
OO
看来些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
   发表时间:2006-12-15  
你加一句system.gc()
以防内存使用优化区别....
jvm 对new有很多变态的优化方式
0 请登录后投票
   发表时间:2006-12-15  
我估计也是垃圾收集引起的差异。
你不妨在创建对象之前,先建立一个大数组,把新对象都依次赋给数组,再比较
0 请登录后投票
   发表时间:2006-12-15  
抛出异常的爱 写道
你加一句system.gc()
以防内存使用优化区别....
jvm 对new有很多变态的优化方式


这样的话,是不是就等于说在正常情况下用new的内存开销比clone大?
如果使用那些优化,clone就没有意义了?
0 请登录后投票
   发表时间:2006-12-15  
我想应该不是垃圾收集的问题,垃圾收集应该是内存资源问题,我的程序应该反应的CPU时间问题,而且这么小的对象,百万个应该不会太大影响到内存。试了下System.gc(),没有明显不同;数组赋值的用意我还不太清楚,还望提点

如果是垃圾收集引起的差异,我想替换着先后运行两种创建对象的方式,以及分别单独运行,应该可以剔除这种差异吧,但我分别试了,结果基本没有太大变化
0 请登录后投票
   发表时间:2006-12-15  
我猜测用数组的意义在于保证这些对象不被回收
楼主现在的代码建立的对象属于用完了就扔,没有保持引用

不过我也弄不清楚保持引用会有什么区别
0 请登录后投票
   发表时间:2006-12-15  
用数组分别保存新建的对象也试过了,百万次运行的结果如下:

1000000 次 new()   用时[共,平均]:953,0
1000000 次 clone() 用时[共,平均]:1907,0

应该不是这个问题
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)放在一起对比的结果也说明了他们确实是针对不同需求的
0 请登录后投票
   发表时间: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应该更省事,毕竟就那几个对象,不差这点时间,对吧?
0 请登录后投票
   发表时间:2006-12-15  
这样说来,clone并没有效率上的优势,仅仅是在操作上带来方便了?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics