Optimisation des conditions booléennes avec opérateurs logiques
Par -Alexandre LEGOUT aka LAlex- le mercredi, janvier 28 2004, 09:41 - AS2 - Lien permanent
Pour ceux qui ne le savent pas encore, lorsque vous utiliser des opérateur booléens dans une condtion (&& ou ||), toutes les conditions ne sont pas forcément testées. En effet, une expression booléenne composée uniquement de && est forcément false si un seul de ses éléments est à false. L'évaluation de l'expression d'arrête donc dés qu'un élément false est trouvé. De la même manière, une expression composée de || est true si un seul de ses élements est à true ... ![]()
L'optimisation de conditions booléennes dans des instructions telles que if(...) ou while(...) passe donc par une estimation des probabilités de chaque expression booléenne unitaire d'être true ou false ... Ainsi, dans une expression &&, nous mettrons en premier les expressions qui ont le plus de chance d'être false, arrêtant ainsi l'évaluation des booléens suivants. ![]()
// Retourne true
Dans le cas donné ici, on sait exactement quel booléen va être retourné, mais de manière générale, il s'agit de faire preuve de bon sens. Il s'agit lors de la conception de ces conditions de faire la part entre la charge induite par l'évaluation d'une expression unitaire, et sa probabilité de mettre fin à l'évaluation de l'expression booléenne entière. Parfois, une condition a plus de chances de mettre fin à l'évaluation, mais provoque beaucoup de calculs, alors qu'une autre partie de l'expression est bien plus rapide à calculer, mais moins de chances d'arrêter l'évaluation. Il faut à ce moment la faire a part des choses entre probabilité et temps d'éxecution. 8|
La négation "!" peut parfois servir à intervertir l'ordre de calcul, et ainsi inverser les probabilités. L'ordre sera à redéterminer en fonction de ca.
function getTrue() {
trace("getTrue");
return true;
}
// Retourne false
function getFalse() {
trace("getFalse");
return false;
}
/* Condition "et" non optimisée
Les deux fonctions sont appelées */
if (getFalse() && getTrue()) {
trace("OK");
}
// - Sortie -
// getTrue
// getFalse
/* Condition "et"
La condition qui a le plus de chances de
retourner false est mise en premier
Ainsi, les condtions suivantes ont moins de
chances d'être executées */
if (getFalse() && getTrue()) {
trace("OK");
}
// - Sortie -
// getFalse
/* Condition "ou" non optimisée
Les deux fonctions sont appelées */
if (getTrue() || getFalse()) {
trace("OK");
}
// - Sortie -
// getFalse
// getTrue
// OK
/* Condition "ou"
La condition qui a le plus de chances de
retourner true est mise en premier
Ainsi, les condtions suivantes ont moins de
chances d'être executées */
if (getTrue() || getFalse()) {
trace("OK");
}
// - Sortie -
// getTrue
// OK
if (getTrue() && getFalse()) {
trace("OK");
}
// est équivalent à
if (!getTrue() || !getFalse()) {
trace("OK");
}
Ce type d'optimisation est souvent négligé, alors que l'utilisation des conditions est trés fréquente en programmation ... Elle s'applique également à la plupart des langages, bien que certains commencent à évaluer les condtions par la fin ...^^
Commentaires
je me sert beaucoup de cette propriété dans des initialisations de propriétés ... par exemple :

function parler (phrase:String) {trace ( phrase || "rien à dire") ;
}
parler ("coucou") ; // sortie : coucou
parler () ; // sortie : rien à dire
si on inverse l'ordre des conditions dans l'expression on n'obtient forcément pas le bon résultat.
Donc faut faire attention
bye
Tiens, je me suis souvent posé la question sans jamais approfondir! Je ne savais pas s'il s'arrêtait après la première évaluation ou s'il testait tout de même bêtement les deux.
Je suis bien content d'apprendre cela, très bon à savoir!
Merde, la tonne de code que je dois réviser là... ouch!
Merci beaucoup pour l'info!
Un grand classique en programmation qui vaut le coup d'être rappelé !
En AS2, les chaines de caractères sont evaluées 'true' ?
A priori, tout ce qui n'est pas 0 ou false ou undefined est évalué à true ...
++ ^^
au fait, c'est marqué où que le reste de la condition n'est pas traité ?
il y a certain langage qui traite tout "bêtement"
lol ah mais chui bête, j'avais meme pas vu le code, j'ai répondu direct
scuzé ... j'vais retourner à Final leveler mon White Mage ....
Et ben (en AS1 en tout cas) une chaine de caractères est évalué à faux (mais c'est le contraire sur MAC je crois).
sur MAC quel rapport
???
Par contre en effet on a :
var a = x || 15 ;var b = x || "coucou" ;
var c = x || true ;
var d = x || false ;
trace ("a : " + a + " --> Bool(a) : " + Boolean (a) ) ;
trace ("b : " + b + " --> Bool(a) : " + Boolean (b) ) ;
trace ("c : " + c + " --> Bool(a) : " + Boolean (c) ) ;
trace ("d : " + d + " --> Bool(a) : " + Boolean (d) ) ;
/* ----- sorties
FLASH 5
a : 15 --> Bool(a) : true
b : coucou --> Bool(a) : false
c : true --> Bool(a) : true
d : false --> Bool(a) : false
FLASH 6
a : 15 --> Bool(a) : true
b : coucou --> Bool(a) : false
c : true --> Bool(a) : true
d : false --> Bool(a) : false
FLASH 7 (AS1)
a : 15 --> Bool(a) : true
b : coucou --> Bool(a) : true
c : true --> Bool(a) : true
d : false --> Bool(a) : false
---- */
bye
Il me semble que sur MAC, le plugin Flash évalue les chaines à vrai lorsque sur PC c'est évalué à faux !
vaudrait mieux pas
function say1(what){
trace(what || 'well, just anything');
}
C'est joli! Mais je préfère le classique 'ternary statement':
function say2(what){
trace(what ? what : 'well, just anything');
}
say1('something');
say1();
say2('something');
say2();
Fil des commentaires de ce billet