Der Titel bezieht sich auf Warum ist es schneller, ein sortiertes Array zu verarbeiten als ein unsortiertes Array?
Ist dies auch ein Verzweigungsvorhersageeffekt? Achtung: Hier ist die Verarbeitung für das sortierte Array langsamer !!
Betrachten Sie den folgenden Code:
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);
...
}
Dies druckt einen Wert von ungefähr 720 auf meinem Computer aus.
Wenn ich jetzt den Sortieraufruf für Sammlungen aktiviere, sinkt dieser Wert auf 142. Warum?!?
Die Ergebnisse sind schlüssig, sie ändern sich nicht, wenn ich die Anzahl der Iterationen / Zeit erhöhe.
Die Java-Version ist 1.8.0_71 (Oracle VM, 64 Bit) und läuft unter Windows 10, JUnit-Test in Eclipse Mars.
AKTUALISIEREN
Scheint mit einem zusammenhängenden Speicherzugriff verbunden zu sein (Doppelte Objekte, auf die in sequentieller Reihenfolge zugegriffen wird, vs. in zufälliger Reihenfolge). Der Effekt verschwindet für mich bei Array-Längen von ca. 10k und weniger.
Vielen Dank an assylias für die Bereitstellung der Ergebnisse :
/**
* 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
*/