Java で長い配列に対して短いベンチマークを実行したところ、非常に奇妙な結果が得られました。ランダム書き込みによるシーケンシャル読み取りは、シーケンシャル書き込みによるランダム読み取りよりも高速 (半分の時間) のようです。誰にも理由はありますか??
以下に、いくつかの long 型の配列 (-Xmx2G などで実行) を、順次読み取り時にランダムに書き込み、ランダム書き込み時に順次読み取りを行う 2 つの方法を示します。
import java.util.Random;
public class Scratch {
static Random random = new Random();
static long[] arr = new long[100000000];
static void seqReadRandWrite() {
for(int i=0;i<arr.length;i++) {
int at = random.nextInt(arr.length);
arr[at] = arr[i];
}
}
static void seqWriteRandRead() {
for(int i=0;i<arr.length;i++) {
int at = random.nextInt(arr.length);
arr[i] = arr[at];
}
}
public static void main(String[] args) throws Exception {
seqWriteRandRead(); // warm up
long nanos = System.nanoTime();
seqReadRandWrite();
System.out.println("Time: " + (System.nanoTime()-nanos) + "ns");
nanos = System.nanoTime();
seqWriteRandRead();
System.out.println("Time: " + (System.nanoTime()-nanos) + "ns");
}
}
私のノートの結果は
時間: 2774662168ns
時間: 6059499068ns
これは、読み取りと比較して、ランダムに書き込む方が2倍速いことを意味します..または? 私のノートは壊れていますか?
ps .: これはベンチマークであるとは主張していませんが、ベンチマークに関するリンクされたアドバイスのほとんどのポイントがカバーされています。すでに 200,000,000 の操作を複数回実行しても、結果は一定に保たれます。少なくともこのサイズのメモリと上記の方法では、ランダムな位置から連続したブロックにメモリを移動するのは、連続した位置からランダムなブロックにメモリを移動するよりも遅いようです。なぜだろう?