私は最近、いくつかのベンチマークで遊んでいて、今説明できない非常に興味深い結果を発見しました。ここでは、ベンチマークは次のとおりです。Arrays.copyOfはSystem.arraycopyよりも2倍高速に配列されていますか?
@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, batchSize = 1000)
@Measurement(iterations = 10, time = 1, batchSize = 1000)
public class ArrayCopy {
@Param({"1","5","10","100", "1000"})
private int size;
private int[] ar;
@Setup
public void setup() {
ar = new int[size];
for (int i = 0; i < size; i++) {
ar[i] = i;
}
}
@Benchmark
public int[] SystemArrayCopy() {
final int length = size;
int[] result = new int[length];
System.arraycopy(ar, 0, result, 0, length);
return result;
}
@Benchmark
public int[] javaArrayCopy() {
final int length = size;
int[] result = new int[length];
for (int i = 0; i < length; i++) {
result[i] = ar[i];
}
return result;
}
@Benchmark
public int[] arraysCopyOf() {
final int length = size;
return Arrays.copyOf(ar, length);
}
}
結果:
Benchmark (size) Mode Cnt Score Error Units
ArrayCopy.SystemArrayCopy 1 thrpt 10 52533.503 ± 2938.553 ops/s
ArrayCopy.SystemArrayCopy 5 thrpt 10 52518.875 ± 4973.229 ops/s
ArrayCopy.SystemArrayCopy 10 thrpt 10 53527.400 ± 4291.669 ops/s
ArrayCopy.SystemArrayCopy 100 thrpt 10 18948.334 ± 929.156 ops/s
ArrayCopy.SystemArrayCopy 1000 thrpt 10 2782.739 ± 184.484 ops/s
ArrayCopy.arraysCopyOf 1 thrpt 10 111665.763 ± 8928.007 ops/s
ArrayCopy.arraysCopyOf 5 thrpt 10 97358.978 ± 5457.597 ops/s
ArrayCopy.arraysCopyOf 10 thrpt 10 93523.975 ± 9282.989 ops/s
ArrayCopy.arraysCopyOf 100 thrpt 10 19716.960 ± 728.051 ops/s
ArrayCopy.arraysCopyOf 1000 thrpt 10 1897.061 ± 242.788 ops/s
ArrayCopy.javaArrayCopy 1 thrpt 10 58053.872 ± 4955.749 ops/s
ArrayCopy.javaArrayCopy 5 thrpt 10 49708.647 ± 3579.826 ops/s
ArrayCopy.javaArrayCopy 10 thrpt 10 48111.857 ± 4603.024 ops/s
ArrayCopy.javaArrayCopy 100 thrpt 10 18768.866 ± 445.238 ops/s
ArrayCopy.javaArrayCopy 1000 thrpt 10 2462.207 ± 126.549 ops/s
だからここ2奇妙なことがあります。
Arrays.copyOf
が小さい アレイ用の2倍System.arraycopy
よりも高速ですが(1,5 、10サイズ)。しかし、サイズの大きな配列では、Arrays.copyOf
はほぼ2倍遅くなります。私は両方の メソッドがintrinsicsであることを知っているので、私は同じパフォーマンスが期待されます。この違いは ですか?- 1要素配列の手動コピーは、
System.arraycopy
よりも高速です。なぜ私には分かりません。誰か知っていますか?
VMのバージョン:JDK 1.8.0_131は、VM 25.131-B11
'copyOf'は内部的に' arraycopy'を使用しているので、あなたのベンチマークが問題です。 – Andreas
@アンドレアスあなたは正しくありません。 'Arrays.copyOf'はJVMの組み込みです。メソッドがJITコンパイルされると、 'Arrays.java'のJavaコードはまったく実行されません。 – apangin
@Andreasベンチマークの特有の問題はありますか?一般的なベンチマークの落とし穴を避けるために、[JMH framework](http://openjdk.java.net/projects/code-tools/jmh/)を賢明に使用します。 – apangin