Reputation: 153
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
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
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
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
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
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
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