"case of " VS "if then"

Résolu
bundyboss Messages postés 28 Date d'inscription mardi 24 juin 2003 Statut Membre Dernière intervention 3 mars 2005 - 15 févr. 2005 à 23:57
aafi Messages postés 24 Date d'inscription mardi 8 février 2005 Statut Membre Dernière intervention 12 janvier 2011 - 3 mars 2005 à 20:16
Salut,
j'aimerai savoir quel traitment est le plus rapide et le moins gournamd en memoire pour faire des actions du genre

case Valeur of
0: i:=1
1: i:=2
.. : i:=..
. : i:=..
300 : i:=3
end;

et
if i:=0 then
i:=1:

if i:=1 then
i:=2;
.....

if i:=300 then
i:=3;

Dans un cas comme ca, mis a part la visibilité il vaut mieux utiliser un case non?
A voir également:

32 réponses

jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
16 févr. 2005 à 18:58
De toute facon on ne peut pas vraiment tout expliquer, en raison de l'optimisation effectué par le compilateur Delphi.

j!nH
0
ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 12
16 févr. 2005 à 19:03
Je retire ce que j'ai dit :
"L'écart se réduit considérablement quand on met "else if" à la place des if de 2 à 59... "

En fait, c'est très variable..... des fois oui, des fois non
Ca dépend de l'utilisation du processeur au moment ou on fait le calcul aussi...


@+
Bonne Prog'
Nico



<HR>
N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
16 févr. 2005 à 19:15
Bon j'ai quelques éléments de réponse, mon affirmation sur les if et les case est vérifiée en C, mais:

Delphi est un peu plus malin.

En examinant le code ASM généré, nous remarquons effectivement un précalcul des différentes valeurs du case. Si valeur de i > valeur max proposée ds le Case alors on retourne au prochain case (TestCase + $35).

Et ainsi de suite, dc cela évince pas mal de tests (ceux du début + ceux ou i >60).

De plus comme les valeurs sont consécutives, dans le case, le saut à effectuer est fixe (multiple de 4octets).

Donc c bien une optimisation du case par Delphi dans ce cas la, et ce n'est pas lié au fonctionnement originelle des deux fonctions.Le meilleur moyen de se le prouver est de mettre des valeurs non consécutives dans le case (saut variable pour atteindre l'instruction donc plus de cycles machines).

Voila ca serait intéressant un jour que quelqu'un approfondisse davantage en faisant un tuto, mais moi je n'ai pas assez de connaissances en asm.

j!nH
0
ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 12
16 févr. 2005 à 19:33
Merci jinh68 pour ces éléments de réponse ! Notre cher Delphi nous joue donc des tours

Pour le tuto, je pourrais pas le faire, l'asm c'est pas trop mon truc... Quelqu'un se sentirait-il capable de le réaliser


@+
Bonne Prog'
Nico



<HR>
N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
bundyboss Messages postés 28 Date d'inscription mardi 24 juin 2003 Statut Membre Dernière intervention 3 mars 2005
16 févr. 2005 à 20:10
neco: ça depend de la version a delphi que tu as, a partir de la version 7 ( me semble ) le Case ... Of est optimisé il fait ses comparaisons par dichotomie

jinh68 tu utilises une version récente de delphi non?
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
16 févr. 2005 à 20:14
Je suis sous delphi 5 en fait, mais je peux aussi faire les tests sous 2005.

Le tri par dichotomie est possible (on travaille sur des intervalles qui rapetissent à chaque fois) mais je n'ai pas su l'identifier par les instructions d'asm(beaucoup de OU exclusif sur le registre al).

j!nH
0
cs_Kenavo Messages postés 702 Date d'inscription vendredi 21 mars 2003 Statut Membre Dernière intervention 1 octobre 2009 5
17 févr. 2005 à 09:24
'scuse pour mod 20, j!nH,
pas fait exprès ! Mea culpa, mea culpa, mea maxima culpa ! J'avais commencé avec 20 valeurs !

Le mieux est de sortir de la boucle l'instruction i:=SecondOf(Now) (elle est longue) on observe mieux le comportement des routines de test.



Et je te cite:

"De plus comme les valeurs sont consécutives, dans le case, le saut à effectuer est fixe (multiple de 4octets)."


1 - La question de Bundyboss était bien dans ce sens !

2 - Si tu enlèves quelques valeurs, l'adresse de la routine inexistante
est remplacée (dans la table) par l'adresse de l'instruction suivant le
case, donc même temps d'éxécution, mais l'occupation mémoire ne diminue pas !



j!nH,



"De toute facon on ne peut pas vraiment tout expliquer, en raison de l'optimisation effectué par le compilateur Delphi."

Ca, c'est ben vrai !
En
remplaçant une suite de nombre consécutifs par quelques valeurs très
éloignées, il remplace la table par une comparaison après soustraction
(delphi 7), et il pert la structure systématique, que je décrivais plus
haut.



j!nH,

La présence de ou exclusif ne
m'étonne pas, c'est la méthode que j'utilise dans tous les assembleurs
pour coder un case of. Mais là je ne l'ai pas vue (Delphi 7). Elle est
utilisée comme suit :

mov ax,valeur

xor ax,premierevaleur

jz premiereroutine


xor ax,(premierevaleur xor deuxiemevaleur)

jz deuxiemeroutine


xor ax,(deuxiemevaleur xor troisiemevaleur)

jz
troisieme
routine

... etc ...

rappels : A xor A 0 ; (A xor B) xor (B xor C) A xor C







Nico,

"L'écart se réduit considérablement quand on met "else if" à la place des if de 2 à 59... "


Ca, c'est pas faux, mais, tu devrais regarder la pendule de ton ordi en même temps, comme le if
regarde la valeur des secondes (dans mon exemple), si tu es dans le
début de la minute, ta comparaison est vraie assez tôt et tu quitte
rapidement, si tu es dans la fin de la minute .... c'est plus long !





Mais si on doit conclure, et pour répondre à la question (valeurs
consécutives de 0 à 300), il semblerait que l'efficacité et sutout
l'élégance nous amènent à préférer Case.



Gardons pour if d'autres avantages incontestables comme le test de variables string ou le test de valeurs supérieures à $FFFF (limite du case).



Et puis, il ne s'agit que de quelques nano-secondes d'écart sur un PC d'aujourd'hui !



Ken@vo

____________________

Code, Code, Codec !
0
bundyboss Messages postés 28 Date d'inscription mardi 24 juin 2003 Statut Membre Dernière intervention 3 mars 2005
17 févr. 2005 à 09:49
Wouaw kenavo!.
Cependant, je souhaite aussi evoqué un autre spécial:
tu dis: Gardons pour if d'autres avantages incontestables comme le test de variables string ou le test de valeurs supérieures à $FFFF (limite du case).

je copie colle un exemple de code!
source: typechaine#caseofstring http://delphi.developpez.com/faq/?page=typechaine#caseofstring

<TABLE width="100%">

----, [http://delphi.developpez.com/faq/?page=typechaine# [haut]]
</TD></TR>
<TR>
<TD class=QA_ligne_autheur>auteur : sjrd</TD></TR>
<TR>
<TD class=QA_ligne_question>

Etant donné que la structure Case Of requiert une donnée de type ordinal, il est impossible de faire un Case Of directement avec des String.
L'astuce consiste à utiliser la fonction AnsiIndexStr de l'unité StrUtils :

uses StrUtils;
...
case AnsiIndexStr(Str, ['Chaîne1', 'Chaîne2', 'Chaîne3']) of
0 : // Str = 'Chaîne1'
1 : // Str = 'Chaîne2'
2 : // Str = 'Chaîne3'
-1 : // Str ne vaut aucune de ces trois chaînes
end;



Si votre version de Delphi ne propose pas cette fonction, elle peut être implémentée comme suit :

function AnsiIndexStr(AText : string; const AValues : array of string) : integer;
begin
Result : = 0;
while Result <= High(AValues) do
if AValues[Result] = AText then exit
else inc(Result);
Result := -1;
end;



Une autre idée, dans le cas d'un Case Of dynamique, est d'utiliser un objet de type TStrings et sa méthode IndexOf
</TD></TR></TBODY></TABLE>
dans un cas comme celui-ci le if est plusr apide non pour comparer des strings? non?!?
0
cs_Kenavo Messages postés 702 Date d'inscription vendredi 21 mars 2003 Statut Membre Dernière intervention 1 octobre 2009 5
17 févr. 2005 à 14:54
Alors là, le problème n'est plus du tout le même ! Pour faire un case sur des string, on se débrouille pour ramener un indice (IndexOf ou
AnsiIndexStr dans les exemples). Or cet indice est retrouvé par une méthode qui doit beaucoup au while (voir la fonction AinsiIndexStr ci-dessus) donc au if ... then ... else



Le case avec des strings dissimule (mal !) une utilisation à la chaîne (!) d'instructions if



Mais l'élégance du source justifie tout à fait une telle utilisation du case.



Ken@vo

____________________

Code, Code, Codec !
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
17 févr. 2005 à 19:22
Merci les gars pour ce débat passionnant.

J'ai bien sûr voulu tester, ça a donné lieu à un code.

Il m'a paru intéressant de le partager, ça peut certainement servir comme base de test plus poussés ?



COMPARER LES INSTRUCTIONS CASE OF, IF THEN ET IF THEN ELSE



bonne prog' à tou(te)s



japee
0
aafi Messages postés 24 Date d'inscription mardi 8 février 2005 Statut Membre Dernière intervention 12 janvier 2011
2 mars 2005 à 23:29
ce forum n° ID 393257 se trouve avoir une continuation dans le forum ID 29593 , à l'initiative je crois de JAPEE

Consultez ce forum, et vous y trouverez d'intéressants débats sur ce sujet

Quant à moi, mes conclusions que vous y trouverez sont sans appels : :

Avantage par K.O. au CASE..OF

* plus rapide ( l'écart se creuse lorsqu'il y a beaucoup de valeurs à tester )
* encombrement mémoire moindre dès lors que les valeurs à tester sont contigues
* élégance du code
* bien meilleur lisibilité du code
* facilité de rajout de nouvelles valeurs
* insensibilité à l'ordonnancement de valeurs ( pas la peine de se prendre la tete pour savoir quel est le cas le plus fréquent)

comme le montre le programme expérimental à JAPEE , un CASE portant sur 60 valeurs est 10 fois plus performant que des IF THEN successifs.

*****
0
aafi Messages postés 24 Date d'inscription mardi 8 février 2005 Statut Membre Dernière intervention 12 janvier 2011
3 mars 2005 à 20:16
OBJET : le CASE OF fonctionne t il par DICHOTOMIE ??

( questions posées par BUNDYBOSS , NEKO , JINH68 ) vers le 16/02/05

REPONSE : OUI dans certains cas , NON dans d'autres ;

Voir mes contributions sur l'autre forum n° ID 29593

et cela n'est pas valable que avec Delphi7 , puisque j'utilise Delphi 5
0
Rejoignez-nous