The project that I am currently working on has lot of objects that are serialized in order to get a deep copy of the the existing object. This works fine until we have multiple calls at runtime in some cased we have 100, 200, or even 1000 calls between components and this is where we are hit with performance headache.
Historical reason for copying these objects being cloned is that , two different component working on same objects under different functionality should not change each other e.g. Changes in Swing UI should not change the object values in backend until save or synchronized button is pressed.
We have quite a large code base, I thought if I would write clone based on reflection it will work faster as compared to serialization , but either due to our complex hierarchies of objects or due to some other reason , this approach is even slower.
I also tried using CloneUtils (sourceforge project) , which is slower as well (We are not using Hibernate at all). Spring BeanUtils is not an option (I assume from docs that it only uses beans i.e. introspection and in case I use it if any fields are exposed using non standard accessor , we will not be able to copy those).
Has anyone any idea , improve the performance while still working on different copies. We have an option which will speed up things in case we provide our own copy methods ,instead of serialization, but that has downside of updating these methods every time and if we forget we might loose functionality.
There are two types of object cloning - shallow cloning, and deep cloning.
parse() and Stingify() methods. Among the above mentioned three ways, for an object to be deep cloned, JSON. stringify() and JSON. parse() functions are used.
clone() is indeed a shallow copy. However, it's designed to throw a CloneNotSupportedException unless your object implements Cloneable . And when you implement Cloneable , you should override clone() to make it do a deep copy, by calling clone() on all fields that are themselves cloneable.
You can avoid reflection by dynamic class generation, e.g., using cglib. For each class you use, you'd generate a "cloner class" containing the code needed for the copy. This would make reflection unnecessary, provided all fields are at least package-private and you put the copier class in the same package. You'd need a default ctor and no final fields, too.
Here, serialization has an advantage, as it creates objects using sun.misc.Unsafe
.
Implementing a deepClone
method in each class could be an option, too. It could be even combined with the cloner-class idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With