Le titre est en référence à Pourquoi le traitement d'un tableau trié de plus qu'un tableau non trié?
Est-ce une branche de prédiction de l'effet, trop? Attention: ici, le traitement pour le tableau trié est plus lent!!
Considérons le code suivant:
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);
...
}
Ceci affiche une valeur de près de 720 sur ma machine.
Maintenant, si je activer les collections de tri appel, cette valeur descend à 142. Pourquoi?!?
Les résultats sont concluants, ils ne changent pas si j'augmente le nombre d'itérations/heure.
Version de Java est 1.8.0_71 (Oracle VM, 64 bits), fonctionnant sous Windows 10, de test JUnit dans Eclipse Mars.
Mise à JOUR
Semble être lié à la mémoire contiguë d'accès (Double les objets accessibles dans l'ordre séquentiel vs dans un ordre aléatoire). L'effet commence à disparaître pour moi pour le tableau des longueurs d'environ 10k et moins.
Grâce à assylias pour fournir les résultats:
/**
* 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
*/