Monthly Archives: October 2013

Why clone is faster than constructor copy

This post is a followup on my previous post about copying objects in Java. After I published that post I got a question from Sven Reimers (@SvenNB) why there is a big performance different between clone and copying via constructor. In this post I will try to answer this question.

Code in question

Just to recap what we are looking at. There are 2 classes implementing copy() method:

  • Copy via clone():
  • Copy via constructor:
  • Both of these classes inherit from the common base class that defines state to be copied:

Clone under the hood

java.lang.Object defines clone() method as native thus giving JVM possibility to use intrinsics. And in fact this is what OpenJDK JVM implementation is doing under the hood:

Unfortunately I was not able to find exactly how such intrinsified clone() method call would look like. If any of you knows the answer I would be more than happy to hear about it!

Test code and results

This time I won’t be using JMH running my tests, because I just need to force JVM to compile methods in question. For each case there is a dedicated test class (i.e. and that invokes copy() method 500 000 times during warmup phase and then another 10 000 000 during actual test phase. These numbers are not particularly relevant and they were chosen to ensure that JVM will compile copy methods into native code.
I will use 1.7.0_45 JDK version.

Here are test classes:

I ran both tests with -XX:+PrintCompilation option and got the following results:

  • Clone:
  • Constructor:

This by itself is not telling us much except that in the second (constructor) case there are 2 more entries that were compiled (i.e. BaseClass::<init> and Root::<init>).

The real fun is to look into generated assembler code (i.e. -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly). If you want to know how to dump assembly you can use java-print-assembly instructions provided by Nitsan Wakart on his blog. Links to proper binaries saved me tons of time today. 😉

I will show here only relevant part of the assembly dumps which contain only compiled callCopy() method from each test class, because it is the one we are interested in:

As you can see clone case has much shorter assembler code and basically it is just an *invokespecial clone invocation. Whereas in the constructor case we see much bigger assembler output and in essence it contains multiple *putfield invocations.

CPU counters

Eventually I managed to compile Intel Performance Counter Monitor 2.5.1 on my OS X 10.9.
Here are the results of running clone and constructor code under PCM (NB: I changed number of iterations to 20'000'000 in test() method for this run):

  • Clone:
  • Constructor:

What this output shows is that clone case is faster because amount of instructions executed is lower, i.e. there is less code to execute:

  • TestClone:

    Instructions retired: 10 G ; Active cycles: 16 G ; Time (TSC): 3425 Mticks

  • TestConstructor:

    Instructions retired: 11 G ; Active cycles: 17 G ; Time (TSC): 3988 Mticks

Copy object in Java (performance comparison)

This blog came about because I was looking into performance issue and profiling showed that a method that was copying objects was very slow. (NB: The fact that this method was called millions of times was an actual bug not the slowness of the copy routine.)

The method to copy object was performing field by field copy using class.getDeclaredFeilds() method to obtain all fields of the class and then doing copy recursively for all super classes. Code below shows entire thing:

Profiling showed that this method spend 70% of it’s time in Field#copy() method. As it turns out that Class#getDeclaredFields() returns a copy of the Field[] array on every call, ouch! BTW, the JavaDoc of Class#getDeclaredFields() does not mention copy behavior at all.

List of approaches

Looking at the profiling results I started wondering what would be a better way to create a shallow copy of the object. Hence I needed to test performance of different approaches. For the simplicity I decided to look only on what is possibly with JDK 7 only (no fancy libraries) and came up with the following list:

  1. Clone object – implement Cloneable interface and publish clone() method
  2. Copy with copy constructor – copy fields from the source object directly in the constructor
  3. Copy via reflection (field by field)
    • getDeclaredFieds() as in original code
    • getDeclaredFields() cached, i.e. call it once and remember list based on the Class
  4. Serialization

    • Default serialization – just implementing Serializable
    • Custom serialization – implement Serialization and implement readObject() and writeObject() methods for reading and writing fields directly
    • Implementing Externalizable interface
  5. MethodHandles
    • Use MethodHandle#invoke(Object... args) method
    • Use MethodHandle#invokeWithArguments(Object... arguments) method
    • Use MethodHandle#invokeExact(Object... args) method

Notes on implementation

Entire project with source code and test results is available on github (copy-object-benchmark.git).

Benchmarks are written using JMH framework from OpenJDK. For each class tested there is a method in the benchmark class that simply invokes copy() method on the constant object representing the class. For example:

Every approach from the list above was benchmarked for 2 cases:

  • Primitive fields
  • Object fields

Because most of the approaches would incur significant overhead via boxing/unboxing.

For every kind of copy method there is a class that extends common super class (i.e. BaseClass) and implements copy() method. Since there are 2 use cases tests had to be duplicated in 2 different packages.

One last thing that is worth mentioning before I show the results is the handling of MethodHandle#invokeExact() case. This method is very special when it gets to invocation. Here is an example:

As you can see in order to call MethodHandle#invokeExact() it is necessary to match exactly arguments and return type of the method, otherwise such invocation will fail at runtime.

However it is not possible to know upfront all possible classes and return types if you want to write generic copy method. Therefore we need to adjust MethodHandle so it can be invoked in a generic manner. This is done by adjusting MethodType signatures of the MethodHandle as shown below:

Basically this erases original information about declaration class and return types and instead uses Object for both thus allowing calling MethodHandle#invokeExact() providing instance of any class and expecting result as Object.


I was running the benchmarks on my MacBook Pro laptop: OS X 10.9, 2.7 GHz Intel Core i7, 16 GB of RAM. Tests were performed on the following JDKs:

  • 1.7.0_25 (1.7.0_25-b15)
  • 1.7.0_45 (1.7.0_45-b18)
  • JDK 8 build 112 (1.8.0-ea-b112)

Results are reported as throughput (operations/ms) with biggest numbers being the best. All charts are in logarithmic scale.


  • JDK 1.7.0_25:
    Raw results are available here results-1.7.0_25.txt.

    So in this version of JDK the best 3 methods were:

    1. Clone
    2. Copy constructor
    3. Reflection

    Also MethodHandles are very slow comparing to other approaches.

  • JDK 1.7.0_45:
    Raw results results-1.7.0_45.txt.

    In the 1.7.0_45 release we see that MethodHandle#invokeExact() got much faster (~5x times) to the point that it made it to top 3 copy methods (for primitives case). Also MethodHandle#invokeWithArguments() got slower. But otherwise the rest remains the same.

  • JDK 8 build 112:
    Raw results results-1.8.0-ea-b112.txt.

    JDK 8 build 112 brings significant performance improvements over JDK 7 results in two areas:

    • Reflection
    • MethodHandles

    Most dramatic change was in the MethodHandler#invoke() case which now is more than 120x times faster! The changes were done originally proposed by John Rose on a JDK mailing list and implemented as part of the JDK-8024761: JSR 292 improve performance of generic invocation issue.

    Along the way MethodHandle#invokeWithArguments() got faster as well.


  • New JDK releases bring performance improvements
  • New JDK versions bring new functionality that can be used in place of old approaches (e.g. MethodHandles)
  • JVM is extremely good at optimizing existing code, i.e. reflection is still faster than invoke dynamic (at least for Object case)
  • Read JavaDoc but step through the code in the debugger and not just through your own code but also JDK code
  • Write performance tests upfront to know whether selected approach meets performance requirements
  • Run performance tests against new JDK versions to avoid/detect performance regressions


I’ve published second blog post Clone vs copy constructor – a closer look in which I analyze performance difference of clone and copy constructor approaches.

Latency Tip Of The Day

"Nothing is more dangerous than an idea when it is the only one you have." (Emile Chartier)

Psychosomatic, Lobotomy, Saw

"Nothing is more dangerous than an idea when it is the only one you have." (Emile Chartier)

"Nothing is more dangerous than an idea when it is the only one you have." (Emile Chartier)

Mechanical Sympathy

"Nothing is more dangerous than an idea when it is the only one you have." (Emile Chartier)