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







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がまったく同じ長さをコピーしていることを理解できる理由を説明しています。 だから私は結論と記事を変更しました







配列のclone



Arrays.copyOf



Arrays.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 array



long array



、およびObject array



バージョンがありbyte array



DONT_INLINE



フラグを使用して、必要に応じて生成されたasmを解析しやすくします。







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








All Articles