比較対象
- 通常のcloneメソッド(シャローコピー)
- 自分で実装したdeepCopy
- Serializableを利用したユーティリティ(DeeCopy)
- ClonerライブラリのDeepCopy
また、 独自実装したdeepCopyを実装するためにdeepClonableインターフェース(deepCloneメソッドのみ)を作成しました。
さらに、それを実装した拡張ArrayList、拡張Stringクラスを実装しています。
結果
グラフの横軸が拡張ArrayListの要素数です。
縦軸がコピーにかかった時間[秒]です。
中身は拡張Stringクラスです(正確にはList<List<String>>)。
結果はjvmに2GByteメモリを割り当てて計測しています。
グラフ上では見えず難いですが、cloneの結果は横軸と重なっています。
簡単な考察
- clone > 独自実装 > Serializable > Clonerライブラリの順で速い
- 通常はcloneメソッドでなんとかする
- deepCopyがどうしても欲しいなら、使用頻度やパフォーマンスと相談して3つのどれか選択すればいい
- cloneはグラフではわからないが要素数に比例している。ただし、他よりかなり高速
- 独自実装をうまくやると高速
- Serializableを用いた方法ではSerializableを実装していないと利用できない制約がある。
- Clonerには制約はない。
- Clonerが遅いのは内部でリフレクションを用いているためである。ただし、コピーするクラスによってはリフレクションの使用を抑え速くなるように工夫されている。
- コピーしたオブジェクトによってはこれと異なる結果になる可能性もある。
ここからは計測に利用したプログラムの説明を載せていきます。
計測プログラム
計測プログラムで用いている各クラスなどを以下に示します。
- com.rits.cloning.Clonerクラス:Clonerライブラリ
- yuu.akron.ucollection.another.ArrayListクラス:拡張ArrayList
- yuu.akron.ucollection.interfaces.another.Listインターフェース:拡張Listインターフェース
- yuu.akron.ulang.DeepCloneUtilsクラス:Serializableを利用したdeepCopyユーティリティクラス
- yuu.akron.ulang.S.Sメソッド:java.lang.Stringクラスを拡張Stringクラスに変更する静的メソッド
- yuu.akron.ulang.Stringクラス:拡張Stringクラス
コピーするのはList<List<List<String>>>型(ArrayList, Stringはそれぞれ拡張した物なので注意)です。
java.util.ArrayListのclone実装(java SE 6)
Serializableを利用したdeepCopy実装
拡張ArrayListのdeepCopy実装:各要素に対してdeepCopyメソッドを実行
拡張StringのdeepCopy実装:イミュータブルなので自分を返す
0 件のコメント:
コメントを投稿