克隆如何比对象创建具有更多性能

时间:2015-02-25 17:29:48

标签: java performance clone cloneable

我试图了解java中clone()方法下面发生了什么,我想知道如何做一个新的调用

public class Person implements Cloneable {

    private String firstName;
    private int id;
    private String lastName;

    //constructors, getters and setters

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person p = (Person) super.clone();
        return p;
    }

}

这是我的克隆代码我想知道下面发生了什么,以及新呼叫之间的区别是什么。

这是我的客户代码

    Person p = new Person("John", 1, "Doe");
    Person p2 = null;
    try {
         p2 = (Person) p.clone();
    } catch (CloneNotSupportedException ex) {
        Logger.getLogger(clientPrototype.class.getName()).log(Level.SEVERE, null, ex);
    }
    p2.setFirstName("Jesus");
    System.out.println(p);
    System.out.println(p2);

5 个答案:

答案 0 :(得分:5)

如果您需要副本,请调用clone(),否则请调用构造函数。
标准克隆方法(java.lang.Object.clone())在不调用构造函数的情况下创建对象的浅表副本。如果需要深层复制,则必须覆盖克隆方法。
并且不要担心性能。
性能取决于克隆方法和构造函数的内容,而不是来自使用的技术(新的或克隆)本身。

编辑:克隆和构造函数不是彼此真正的替代品,它们满足不同目的

答案 1 :(得分:4)

public void testPerformance(){
    SimpleDateFormat sdf  = new SimpleDateFormat("yyyy-MM-dd");
    long start = System.currentTimeMillis();
    for(int i = 0; i < 1000000; i++){
        SimpleDateFormat localSdf = (SimpleDateFormat)sdf.clone();
    }
    System.out.println("Cloning : " + (System.currentTimeMillis() - start) + " ms");

    start = System.currentTimeMillis();
    for(int i = 0; i < 1000000; i++){
        Object localSdf = new SimpleDateFormat("yyyy-MM-dd");
    }
    System.out.println("Creating : " + (System.currentTimeMillis() - start) + " ms");

}

克隆:302毫秒 创建:885毫秒

答案 2 :(得分:3)

我为班级Person创建了simple benchmark

public class Person {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

得到以下结果:

Benchmark             Mode  Cnt     Score       Error   Units

MyBenchmark.viaClone  avgt   10     10.041 ±    0.059   ns/op
MyBenchmark.viaNew    avgt   10      7.617 ±    0.113   ns/op

这个简单的基准测试表明,实例化新对象并从源对象设置相应的属性所需的时间比克隆它少25%。

答案 3 :(得分:1)

约阿希姆是对的。如果您需要复制使用克隆,如果您需要一个单独的对象(对于一个单独的人),您应该使用new并创建一个新的对象。

'更多表现'是主观的,可能不是正确的术语。克隆中发生的是底层对象是共享的,即它们对同一内存位置有2个单独的引用。因此,您可以有效地节省创建对象和内存。还记得深拷贝/浅拷贝吗?

答案 4 :(得分:0)

我的要求是为一个类创建1000个对象。所有这些对象共享大多数属性。因此,我决定创建一个具有公共属性的基础对象,并将其克隆到克隆对象集对象特定属性上。这会对性能产生什么影响?我尝试了与上面相同的例子,采用不同的方法,我注意到没有太多稳定的性能差异。这是我的代码和结果。

import java.util.*;
import java.util.stream.*;
import java.text.*;
public class Test{
    public static void main(String[] args){

        try{
            SimpleDateFormat sdf  = new SimpleDateFormat("yyyy-MM-dd");
            long start = System.currentTimeMillis();
            SDFHolder holder = new SDFHolder();
            holder.setSdf(sdf);
            for(int i = 0; i < 1000000; i++){
                SDFHolder locHolder = (SDFHolder)holder.clone();
            }
            System.out.println("Cloning : " + (System.currentTimeMillis() - start) + " ms");
            start = System.currentTimeMillis();
            for(int i = 0; i < 100000000; i++){
                SDFHolder locHolder = new SDFHolder();
                locHolder.setSdf(sdf);
            }
            System.out.println("Creating : " + (System.currentTimeMillis() - start) + " ms");
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}
class SDFHolder implements Cloneable {
    private SimpleDateFormat sdf;

    public void setSdf(SimpleDateFormat sdf){
        this.sdf = sdf;
    }

    public SimpleDateFormat getSdf(){
        return this.sdf;
    }

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}

结果是

C:\Users\thangaraj.s\Desktop>java Test
Cloning : 15 ms
Creating : 0 ms

C:\Users\thangaraj.s\Desktop>java Test
Cloning : 16 ms
Creating : 0 ms

C:\Users\thangaraj.s\Desktop>java Test
Cloning : 0 ms
Creating : 15 ms

C:\Users\thangaraj.s\Desktop>java Test
Cloning : 0 ms
Creating : 16 ms

C:\Users\thangaraj.s\Desktop>java Test
Cloning : 16 ms
Creating : 0 ms

因此,我不认为这些会对这些产生巨大的性能影响,但在我的要求下会提供更简洁的代码。