Comparer les instructions case of, if then et if then else

Soyez le premier à donner votre avis sur cette source.

Vue 17 528 fois - Téléchargée 748 fois

Description

Petit test très minimal affichant la durée d'exécution en ms pour chaque instruction dans une boucle paramétrable.

Suite à une question très pertinente posée par bundyboss sur le forum :

http://www.delphifr.com/forum.v2.aspx?ID=393257

et animé de manière passionnante par Kenavo, jinh68 et ni69, j'ai voulu vérifier par moi-même.

Pour ce faire, j'ai largement utilisé l'idée et le code de Kenavo, que j'ai quasiment copié-collé pour les trois procedures.

Il m'a paru intéressant de contrôler la valeur de la variable testée afin de vérifier deux ou trois choses que l'on pressent :

- si la condition est satisfaite au tout début de la suite d'instructions conditionnelles, l'avantage va à if then else;

- case of reprend très vite l'avantage;

- if then, bien que forcément très stable quelle que soit la valeur de la variable testée, semble pas mal dépassé;

- case of semble d'une régularité et d'une rapidité remarquables;

Voilà, ça semble finalement assez logique, avec une grosse surprise quand même pour l'efficacité de case of.

Sinon, pour le principe du test, très inspiré par Kenavo :

- on teste une variable dans une boucle de 0 à 59 qui affectera cette valeur à la variable, ce qui permet de vérifier l'incidence de cette valeur à l'intérieur des instructions comparées;

- les instructions à comparer sont répétées dans une boucle suffisamment étendue pour que les valeurs soient significatives, que l'on peut paramétrer avec l'interface;

- les résultats sont exprimés en millisecondes et apparaissent dans les memos respectifs dans un ordre de 0 à 59;

- la moyenne des durées de traitement est calculée et affichée dans les edits correspondants.

Voilà, je me suis bien amusé.

Merci à tous, on a vraiment par moments des forums passionnants sur Delphifr ! ;)


Mise à jour du 20-02-05

J'ai rajouté la procedure de Manchester dans le quatrième memo.

Elle "ratatine" toutes les autres !

Petit plus :

Le résultat des tests peut maintenant être enregistré dans un fichier Result.txt, les enregistrements suivants s'appelleront Result001.txt, Result002.txt, etc, donc pas de risque d'écrasement.

Détail amusant (ouais, mais quand même...) et inexpliqué :

Renommez, pour voir, le bouton servant à la sauvegarde de "BtnSaveFile" en "BtnSave".
Les temps d'exécution sont quasiment doublés !!!
J'ai failli virer bredin complet, avant de résoudre ce problème, mais je pas encore compris le pourquoi du comment de cet état de fait...

Conclusion :


Vous pouvez modifier/bidouiller ce code, c'est fait pour !

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
Je réponds à GrandVizir , bien que Kenavo l'ai fait correctement, mais j'ai l'impression que cela n'a pas été bien compris

soit un test tel que :
if (Bidule 1) and (Ma_Super_Fonction(X) true) then begin
.......... faire ceci
end ;

dans lequel Bidule est le plus souvent à ZERO

---------------------------------------------------------
En mode {$B-}, qui est le MODE PAR DEFAUT !
a chaque fois que Bidule est différent de 1 , le test est évidemment FALSE ( à cause du AND ) , et la deuxième partie n'est pas exécutée;
on gagne donc son temps d'exécution, ce qui peut être super interessant, par exemple si Ma_Super_Fonction est un énorme calcul mathématique ( genre résolution d'équation différentielle)

A contrario, avec le mode explicite {$B+}, les 2 parties du test sont systématiquement exécutées et évaluées.
---------------------------------------------
Alors, pourquoi diable avoir prévu une directive qui , A PREMIERE VUE, ne fait que gaspiller du temps processeur ?
Tout simplement parce que vous voulez absolument que Ma_Super_Fonction() soit réellement exécutée à chaque fois...
Vous n'en voyez pas l'utilité ???

Et bien, imaginez par exemple que Ma_Super_Fonction()
* effectue un tracé graphique sur l'écran ==> vous risquez de ne jamais rien voir ...
* examine le Registre Windows, pour voir si quelqu'un ( un spyware) n'y aurait pas modifié quelque chose ==> votre programme sera un grosse passoire
* examine si un fichier toto.xx n'aurais pas été déposé par quelqu'un dans un répertoire sur le serveur central de votre réseau d'entreprise ==> vous risquez de ne jamais remonter l'alerte ...

etc ...
-------------------------------------------
Bien sur, comme le dit MAURICIO, on peut coder la chose différemment, pour contourner le problème :
* on peut par exemple inverser l'ordre des tests :

if (Ma_Super_Fonction(X) true) and (Bidule 1) then

* on peut user de variables temporaires intermédiaires:
BOOL1 :(Ma_Super_Fonction(X) true) ;
BOOL2 :(Bidule 1) ;
if BOOL1 and BOOL2 then begin ......


Conclusion : BORLAND n'a pas voulu vous imposer une manière d'écrire les programmes, et vous laisse libre....

Alors, ne nous pleignons pas !
==============
NOTA important : {$B} n'est pas une directive GLOBALE, comme certaines autres ;
Vous pouvez en mettre plusieurs dans votre programme, ou dans chaque unité.
Donc, si vous avez une raison d'utiliser {$B+}, vous pouvez le circonscrire exactement à la portion de code ou cela à une importance , exemple :

//... début de mon Implementation ............
{$B-}
........ instructions ......
{$B+}
if (Mon_Drapeau_Reseau(1) = true) and
(Ma_Super_Fonction(X) = true) then begin
.......... faire ceci
end ;
{$B-}
........ autres instructions ......

==============
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5 -
Oui mais dans ce cas là, y a qu' a faire :

procedure ;

function3: boolean;
begin
RESULT := fonction1;
if not fonction2
else RESULT := false;
end;

begin
while fonction3 do
begin
...
end;

la directive $B- est très interessante, si si!
Elle permet de speeder les tests et de faire comme dans l' exemple que j' ai mis + haut : )
cs_Kenavo
Messages postés
756
Date d'inscription
vendredi 21 mars 2003
Statut
Membre
Dernière intervention
1 octobre 2009
1 -
Grandvizir,

$B+ peut avoir son importance ! Prends par exemple cette boucle :

while fonction1 and fonction2 do
begin
.....
end;

où fonction1 et fonction2 sont deux fonctions booléennes. Si tu veux être sur que les deux fonctions soient exécutées un même nombre de fois - pour une raison ou pour une autre - la directive $B+ est indispensable. Si fonction1 est fausse la première, elle aura été exécutée et fonction2 ne le sera pas !

Ken@vo
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5 -
Merci GrandVizir !!!
Ça explique pourquoi dans une version antérieure à Delphi7 j' avais le code qui faisait tous les tests alors que ce n' était pas la peine.

On ne pouvait pas écrire un truc dans le genre :

if (i<=liste.items.count-1) and (liste.items[i] = 'xxx')
then begin

end;

Je pensais que c' etait encore la cas jusqu' à la date de cette source !!!!!!!!!!!!!

Obrigado SUPER GrandVizir !!!
cs_grandvizir
Messages postés
1237
Date d'inscription
samedi 8 novembre 2003
Statut
Membre
Dernière intervention
3 septembre 2006
10 -
==============
Je voulais aussi repréciser une chose sur la vitesse d'analyse des conditions via la directive de compilation $B, qui est dans l'état $B- par défaut. Avec D3, on a ce qui suit:

AVEC B-:
CaseOfEnd: 28
IfThen: 138
IfThenElse: 77
AVEC B+:
CaseOfEnd: 30
IfThen: 157
IfThenElse: 85

==============
Dans l'aide, voici ce qu'on peut lire:

La directive $B permet d'alterner entre les deux modèles de génération de code pour les opérateurs booléens and et or.

En mode {$B+}, le compilateur génère un code évaluant entièrement les expressions booléennes. Tous les opérandes des expressions booléennes contenant des opérateurs and et or sont alors évalués, même si le résultat de l'expression totale est déjà connu.

En mode {$B-}, le compilateur génère un code d'évaluation "court-circuit" des expressions booléennes. Cela signifie que l'évaluation s'arrête à partir du moment où le résultat de l'expression devient évident dans l'ordre d'évaluation de gauche à droite.

Pour plus d'informations, recherchez "opérateurs booléens" dans l'index de l'aide du langage Pascal Objet.

==============
On peut alors se poser la question du pourquoi Delphi propose un mode $B+.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.