コピーとクローンを扱っています


Naresh Joshiによるコピーとクローン作成に関する記事に出会い、パフォーマンスの状況に驚きました。 クローニングには最終フィールドに問題があります 。 また、 Cloneableインターフェイスがcloneメソッドを提供しないという事実を考えると、 cloneを呼び出すクラスの特定のタイプを知る必要があります。


次のようなコードを書くことができます。


  ((Cloneable)o).clone(); //   

Cloneableインターフェイスが破損している場合、クローニングメカニズムにはいくつかの利点があります。 メモリをコピーする場合、フィールドごとにコピーするよりも効率的です。 これは、Effective Javaの著者であるJosh Bloch によって強調されています。


ダグ・リーはさらに進んだ。 彼は、アレイをコピーするときにのみクローンを作成するようになったと言いました。 全体としてこれが最速の方法であるため、アレイをコピーするクローンを使用する必要があります。 しかし、Dougでは、型はCloneable実装しなくなりました。 彼は彼と打ち合った。 そして、これは不合理だとは思いません。

しかし、それは2002年でしたが、状況は変わっていませんか? Java 6以降、 Arrays.copyOfがありArrays.copyOf 、それについてはどうですか? オブジェクトのコピーのパフォーマンスはどうですか?
見つける方法は1つしかありません。ベンチマークを取り除くことです。


TL; DR



画像


配列


[UPD] Andrei Paguinは、ベンチマークに問題があるとコメントで指摘しました。


ベンチマークのArrays.copyOf()で「size」を「original.length」に置き換えます。

そして、私はそのことに気づきました...これは、jitがまったく同じ長さをコピーしていることを理解できる理由を説明しています。 だから私は結論と記事を変更しました


配列のcloneArrays.copyOfArrays.copyOfに見てみましょう。


ベンチマーク int arrayは次のようになります。


  @Benchmark @CompilerControl(CompilerControl.Mode.DONT_INLINE) public int[] testCopy() { return Arrays.copyOf(original, original.length); //   size } @Benchmark @CompilerControl(CompilerControl.Mode.DONT_INLINE) public int[] testClone() { return original.clone(); } 

ランダムな数値の配列を作成し、 cloneまたはArrays.copyOf 。 注:コードが実行されるように、コピー結果を返しました。 エスケープ分析の章では、配列が返されないことがベンチマークに根本的な影響を与えることがわかります。


int array byte arraylong array 、およびObject arrayバージョンがありbyte arrayDONT_INLINEフラグを使用して、必要に応じて生成されたasmを解析しやすくします。


 mvn clean install java -jar target/benchmark.jar -bm avgt -tu ns -rf csv 



Source: https://habr.com/ru/post/J334176/


All Articles