Object.clone()の性能

Objectにはclone()というメソッドが存在します。このメソッドは自身と同じ内容のオブジェクトを新たに生成してそれを返却します。
コピー元のオブジェクトが保持しているオブジェクトに関しては同一のものを参照するので、自分の頭の中のイメージとしてはオブジェクト用に確保した領域に対してmemcpyを行っているイメージ。
このメソッドはprotectedで実装されており、なおかつコピー元のオブジェクトがCloneableを実装してないとCloneNotSupportedExceptionを発生するのでちょっと使いにくい。
どのように使用するべきかの実装例を探してみたらいいのが見つかったので引用。

public class Foo implements Cloneable {
    public Object clone() {
        try {
            return (super.clone());
        } catch (CloneNotSupportedException e) {
            throw (new InternalError(e.getMessage()));
        }
    }
}

引用元:クローンナブル


コピーコンストラクタを作成してオブジェクトの複製を作成した場合との性能差が気になったので下記のようなテストクラスを作成して実行してみました。

public class TestClone implements Cloneable {
	
	private static final int SET = 10;
	private static final int ROOP = 100000;
	
	private int value1;
	private int value2;
	private int value3;
	
	public static void main(String[] args) {
		
		int i;
		long time;
		TestClone test = new TestClone();
		
		for (int cycle = 0; cycle < SET; ++cycle) {
			time = System.nanoTime();
			for (i = ROOP; i > 0; --i) {
				new TestClone(test);
			}
			System.out.println("COPY[" + cycle + "]  " + (System.nanoTime() - time));
			time = System.nanoTime();
			for (i = ROOP; i > 0; --i) {
				test.clone();
			}
			System.out.println("CLONE[" + cycle + "] " + (System.nanoTime() - time));
		}
	}
	
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			throw new InternalError(e.getMessage());
		}
	}
	
	public TestClone() {
		value1 = 1;
		value2 = 2;
		value3 = 3;
	}
	
	public TestClone(TestClone src) {
		value1 = src.value1;
		value2 = src.value2;
		value3 = src.value3;
	}
}


実行結果

COPY[0]  10954208
CLONE[0] 41769220
COPY[1]  2810436
CLONE[1] 38234045
COPY[2]  1876126
CLONE[2] 26948310
COPY[3]  1970632
CLONE[3] 27934632
COPY[4]  1601817
CLONE[4] 25787446
COPY[5]  1805355
CLONE[5] 25462086
COPY[6]  3114246
CLONE[6] 28914970
COPY[7]  1825418
CLONE[7] 26942646
COPY[8]  3111301
CLONE[8] 28188760
COPY[9]  1574968
CLONE[9] 26175436


…コピーコンストラクタの方が断然速い。
Object.clone()はnativeなのでnativeメソッド呼び出しに時間がかかっているのではないかと予測。
この結果を見てObject.clone()がさらに使いにくくなりました。