lfernandez93
lfernandez93

Reputation: 153

How clone has more performance than object creation

I'm trying to understand what's happening underneath the clone() method in java, I would like to know how is better than doing a new call

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;
    }

}

this is my clone code i would like to know what's happening underneath and also what's the difference between a new call because.

this is my client code

    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);

Upvotes: 11

Views: 14595

Answers (6)

Alex Bo
Alex Bo

Reputation: 1

It also depends on the number of fields and complex stored structures that will need to be cloned using the deep method. I came across a similar task where you need to give away a typical object as quickly as possible in 99% of cases and the object is very complex in content. Therefore, I am now considering the option to store the prepared binary object as a response template, and clone it and deploy it to the desired class. In theory, it can be faster, especially cloning for structurally complex objects. but I don't know how effective it will be to convert a cloned object from a binary format to a class

Upvotes: 0

Andrii Abramov
Andrii Abramov

Reputation: 10773

I have created simple benchmark for class Person:

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;
    }
}

And got the following results:

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

This simple benchmark demonstrates that instantiating new object and setting corresponding properties from source object takes 25% less time than cloning it.

Upvotes: 7

thangaraj
thangaraj

Reputation: 523

My requirement is to create 1000's of object for a class. All those objects shares most of the properties in common. Hence I decided to create one base object with common properties and clone it and on cloned object set object specific properties. What will be the performance impact on this?. I tried out same example as above, with different approach and I noticed no much stable performance difference. Here are my code and results.

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();
    }

}

And results are

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

So, I don't think there is a huge performance impact on these but gives more concise code in-case of my requirement.

Upvotes: 1

Laurent L&#233;onard
Laurent L&#233;onard

Reputation: 77

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");

}

Cloning : 302 ms Creating : 885 ms

Upvotes: 6

Kedar Parikh
Kedar Parikh

Reputation: 1271

Joachim is right. If you need copy use Clone, If you need a seprate object (for a seprate person) you should use new and create a new Object instead.

'More Performance' is subjective and may not be the right term here. What happens in clone is the underlying objects are shared, i.e. they have 2 seprate references to the same memory location. So effectively you save up creating objects and memory. Remember Deep copy / Shallow Copy?

Upvotes: 1

Gren
Gren

Reputation: 1854

If you need a copy, call clone(), if not, call a constructor.
The standard clone method (java.lang.Object.clone()) creates a shallow copy of the object without calling a constructor. If you need a deep copy, you have to override the clone method.
And don't worry about performance.
Performance depends on the contents of the clone method and the constructors and not from the used technique(new or clone) itself.

Edit: Clone and constructor are not really alternatively to each other, they fullfill different purposes

Upvotes: 11

Related Questions