Inspiré par cette question : Pourquoi est-il plus rapide de traiter un tableau trié qu'un tableau non trié ?
J'ai écrit ma propre expérience de prédiction de branchement :
public class BranchPrediction {
public static void main(final String[] args) {
long start;
long sum = 0;
/* Pas de branchement */
start = System.nanoTime();
sum = 0;
for (long i = 0; i < 10000000000L; ++i)
sum += i;
System.out.println(System.nanoTime() - start);
System.out.println(sum);
/* Avec branchement */
start = System.nanoTime();
sum = 0;
for (long i = 0; i < 10000000000L; ++i)
if (i >= 0)
sum += i;
System.out.println(System.nanoTime() - start);
System.out.println(sum);
/* Pas de branchement (encore) */
start = System.nanoTime();
sum = 0;
for (long i = 0; i < 10000000000L; ++i)
sum += i;
System.out.println(System.nanoTime() - start);
System.out.println(sum);
/* Avec branchement (encore) */
start = System.nanoTime();
sum = 0;
for (long i = 0; i < 10000000000L; ++i)
if (i >= 0)
sum += i;
System.out.println(System.nanoTime() - start);
System.out.println(sum);
}
}
Le résultat me laisse perplexe : selon la sortie du programme, la boucle avec un branchement est systématiquement plus rapide que les boucles sans branchement.
Exemple de sortie :
7949691477
-5340232226128654848
6947699555
-5340232226128654848
7920972795
-5340232226128654848
7055459799
-5340232226128654848
Pourquoi est-ce le cas ?
Éditer :
- La classe désassemblée montre que le compilateur Java n'a rien optimisé (https://gist.github.com/HouzuoGuo/5692424)
- La technique de benchmark Java utilisée par l'auteur de Pourquoi est-il plus rapide de traiter un tableau trié qu'un tableau non trié ? est la même que la mienne.
- La machine est un Intel core i7, exécutant Linux 3.2 64-bit et Oracle JVM 1.7 64-bit
- Quand j'augmente le nombre d'itérations de la boucle, la boucle avec branchement s'exécute en plusieurs SECONDES plus rapidement que la boucle sans branchement.