タイトルはWhy is it faster to process a sorted array than an unsorted array?を参照していますソートされた配列を未処理の配列よりも処理速度が遅くなっているのはなぜですか? (JavaのArrayList.indexOf)
これもブランチ予測効果ですか?注意:ここではソートされた配列の処理は遅いです!
private static final int LIST_LENGTH = 1000 * 1000;
private static final long SLOW_ITERATION_MILLIS = 1000L * 10L;
@Test
public void testBinarySearch() {
Random r = new Random(0);
List<Double> list = new ArrayList<>(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) {
list.add(r.nextDouble());
}
//Collections.sort(list);
// remove possible artifacts due to the sorting call
// and rebuild the list from scratch:
list = new ArrayList<>(list);
int nIterations = 0;
long startTime = System.currentTimeMillis();
do {
int index = r.nextInt(LIST_LENGTH);
assertEquals(index, list.indexOf(list.get(index)));
nIterations++;
} while (System.currentTimeMillis() < startTime + SLOW_ITERATION_MILLIS);
long duration = System.currentTimeMillis() - startTime;
double slowFindsPerSec = (double) nIterations/duration * 1000;
System.out.println(slowFindsPerSec);
...
}
これは私のマシン上での周りの720の値を出力します:
は、次のコードを考えてみましょう。
私はコレクションソートコールをアクティブにすると、その値は142にまで下がります。なぜ?!?
結果がの場合はとなり、反復回数を増やすと変化しません。
Javaのバージョンは、Windows 10で実行されている1.8.0_71(Oracle VM、64ビット)、Eclipse MarsでのJUnitテストです。
UPDATE
(ダブルオブジェクトがランダムな順序で対順番にアクセスされる)連続するメモリアクセスに関連すると思われます。アレイの長さが約10k以下の場合、効果が消えてしまいます。 the resultsを提供するためのassyliasへ
ありがとう:
/**
* Benchmark Mode Cnt Score Error Units
* SO35018999.shuffled avgt 10 8.895 ± 1.534 ms/op
* SO35018999.sorted avgt 10 8.093 ± 3.093 ms/op
* SO35018999.sorted_contiguous avgt 10 1.665 ± 0.397 ms/op
* SO35018999.unsorted avgt 10 2.700 ± 0.302 ms/op
*/
[なぜソートされていない配列よりも速くソートされた配列を処理している?]の可能な重複(http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an -unsortedアレイ) –
http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java –
@DoubleDoubleはい、分岐予測は、言語に依存しない –