Je suis en train d'écrire un peu de code en Java où, à un certain point, le flux du programme est déterminé par le fait que deux variables de type int, "a" et "b", sont non nuls (note: a et b ne sont jamais négatifs, et jamais à l'intérieur de dépassement d'entier).
Je peux l'évaluer avec
if (a != 0 && b != 0) { /* Some code */ }
Ou sinon
if (a*b != 0) { /* Some code */ }
Parce que j'attends de ce morceau de code à exécuter des millions de fois par run, je me demandais ce qui serait plus rapide. J'ai fait l'expérience, en les comparant sur un énorme généré de façon aléatoire tableau, et j'étais également curieux de voir comment la densité de la matrice (fraction de données = 0) aurait une incidence sur les résultats:
long time;
final int len = 50000000;
int arbitrary = 0;
int[][] nums = new int[2][len];
for (double fraction = 0 ; fraction <= 0.9 ; fraction += 0.0078125) {
for(int i = 0 ; i < 2 ; i++) {
for(int j = 0 ; j < len ; j++) {
double random = Math.random();
if(random < fraction) nums[i][j] = 0;
else nums[i][j] = (int) (random*15 + 1);
}
}
time = System.currentTimeMillis();
for(int i = 0 ; i < len ; i++) {
if( /*insert nums[0][i]*nums[1][i]!=0 or nums[0][i]!=0 && nums[1][i]!=0*/ ) arbitrary++;
}
System.out.println(System.currentTimeMillis() - time);
}
Et les résultats montrent que, si vous vous attendez à "a" ou "b" être égal à 0 plus de ~3% du temps, en a*b != 0
plus rapide que de l' a!=0 && b!=0
:
Je suis curieux de savoir pourquoi. Quelqu'un pourrait jeter un peu de lumière? Est-ce que le compilateur ou est-il au niveau du matériel?
Edit: par curiosité... maintenant que j'ai appris à propos de la direction de la prévision, je me demandais ce que l'analogique comparaison serait pour OU b est non nul:
Nous voyons le même effet de la direction de la prévision comme prévu, il est intéressant de noter que le graphique est un peu retourné le long de l'axe des abscisses.
Mise à jour
1 - j'ai ajouté !(a==0 || b==0)
à l'analyse pour voir ce qui se passe.
2 - j'ai aussi inclus des a != 0 || b != 0
, (a+b) != 0
et (a|b) != 0
de la curiosité, après avoir appris direction de la prévision. Mais ils ne sont pas logiquement équivalent aux autres expressions, parce que seulement un OU b doit être non nulle pour renvoyer la valeur true, alors qu'ils ne sont pas destinés à être comparés pour l'efficacité du traitement.
3 - j'ai aussi ajouté le réel de l'indice de référence que j'ai utilisé pour l'analyse, qui est juste une itération à l'arbitraire d'un variable int.
4 - Certaines personnes ont été suggérant d'inclure a != 0 & b != 0
plutôt a != 0 && b != 0
, avec la prédiction que celui-ci se comporte de plus près à l' a*b != 0
parce que nous priverait de la direction de la prédiction de l'effet. Je ne savais pas qu' &
peut être utilisé avec des variables booléennes, je pensais que c'était seulement utilisé pour les opérations binaires avec des entiers.
Remarque: Dans le contexte que j'ai été en considérant tout cela, int débordement n'est pas un problème, mais c'est certainement un facteur important dans les contextes généraux.
PROCESSEUR: Intel Core i7-3610QM - @ 2.3 GHz
Java version: 1.8.0_45
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build à 25,45-b02, en mode mixte)