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

Messages postés
1418
Date d'inscription
samedi 12 juin 2004
Statut
Membre
Dernière intervention
5 juillet 2010
- - Dernière réponse : aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
- 16 mars 2005 à 20:12
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/29593-comparer-les-instructions-case-of-if-then-et-if-then-else

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+.
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
Voila, c'est fait ,
j'ai ouvert un message n° ID=406173 intitulé
DOTNET (.NET) : Utilité, Avantages, Contraintes

dans le thème DIVERS

j'espère avoir correctement traduit les intérrogations posées,
et j'espère ne pas vous avoir trahi !!!

Delphi#
******
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24 -
"L'assembleur peut dans une certaine limite être traduit en .net," : alors là, on tourne en rond. Ecrire en assembleur pour produire du langage de haut niveau, c'est bon pour les hobbyistes.
Comment générer du code CLI, qui est un langage orienté objet, à partir d'instructions destinées à un processeur qui ne possède qu'un jeu d'instructions réduit ?

Comme on sort un peu (?) du sujet et des débats qu'a voulu susciter Japee, je propose qu'on continue sur le forum ce genre de discussion. Qui ouvre le topic ?
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
Lol, faut lire CLI pas CLR qui est le runtime en question...

Bon Coding....

ManChesTer.
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
Delphiprog :

1. Encore faut-il avoir besoin de .Net (j'en veux po pour plusieurs raisons, mais c'est un autre débat..)

2. le CLR n'est jamais traduit en code machine, il interprètè par un runtime, si on dit que CLR est traduit en code machine, alors nimporte quel scripting l'est aussi... Cela fait partie de la lourdeur et de la vulnérabilité de .Net.

3. L'assembleur peut dans une certaine limite être traduit en .net, pourquoi boland ne suivrait-il pas dans le futur. Il me semble avoir lu quelque chose à se sujet sur les site borland.
Pour l'asm .Net voir : http://www.viksoe.dk/code/all_net.htm

4. Quand a Kylix, l'arret du produit est une décision purement financière (politique dirons certains). Borland avais pris cette décision avant même l'apparition de .net....

Bon Coding....

ManChesTer.
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24 -
A la proposition "a", la réponse est : oui.
Le compilateur de Delphi, tout comme celui de tous les langages pour .Net produit du CIL (Common Intermediate Language). Ce code ne sera traduit en langage machine qu'au moment de l'exécution finale par le CLR (Common Language Runtime) pour donner du code binaire en fonction du processeur utilisé à ce moment là. On peut d'ailleurs faire un parallèle avec le code produit par les compilateurs Java qui n'est qu'un code intermédiaire traduit, lui aussi, par la JVM au moment de l'exécution.

A la proposition 'b' : la réponse est non. Cela est dû aux spécifications de la plateforme .Net. Il n'y a donc aucun espoir à avoir et les applications contenant du code ASM devront être revues pour être acceptées sous .Net.

Le côté positif de la chose, c'est qu'un code écrit avec un langage .Net devrait (notez la prudence des propos) pouvoir s'exécuter sur les plateformes Linux grâce au framework Mono (l'équivalent du Microsoft .Net framework sous Linux).
Vous comprendrez alors mieux pourquoi Kylix n'évoluera plus.
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
merci DELPHIPROG , voila une info très utile ;
quant à savoir si c'est "sans" équivoque :
a) soit c'est une impossibilité technique, et alors cela signifie que l'asm inline est définitivement condamné avec le .NET
b) soit cela signifie que Borland a sorti un peu trop vite son Delphi8, et n'a pas eu le temps d'y inclure cela

la REPONSE est à mon avis dans DELPHI2005 : le premier d'entre nous qui aura ce produit en main pourra vérifier si la chose se confirme ou s'infirme !
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24 -
Extrait de la documentation livrée avec Borland Delphi 8:
"Présentation de la syntaxe assembleur (Win32 uniquement)

L'assembleur en ligne est disponible uniquement dans le compilateur Delphi Win32. Les rubriques suivantes décrivent les éléments nécessaires à une utilisation correcte de la syntaxe assembleur.
"
Cela a le mérite d'être sans équivoque.
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
aafi,

tu sais Cpu 20ghz sur des bus qui dépassent à peine 200mz.. is't a sens ?

Bon Coding...

ManChesTer.
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
Bravo MANCHESTER ! d'apporter de l'eau au moulin dans le meme sens que moi :

a) de ramer à contre sens de ceux qui s'imaginent que la "Portabilité" et la "Reutilisabilité" serait le monopole des languages de "haut niveau" , et que les languages plus au raz des paquerettes ( l'ASM , le Forth par exemple) en seraient exclus comme des pestiférés

b) de donner envie aux curieux d'aller voir le "VisualASM" , et qu'avec des bibliothèques et macros ad-hoc, on arrive à un niveau agréable.

c) d'affirmer que l'ASM est parfaitement utile dans certains problèmes , qu'il faut l'utiliser à bon escient et aux endroits critiques sans en abuser cqfd.

le seul qui te fusillera, c'est INTEL qui ne pourra pas vendre aussi facilement son P5 20gigaHz !
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
Mais qui vous à fait croire que l'asm d'aujourd'hui n'est pas portable ?????

En effet si je fais un code asm qui utilise des libs de macros qui elles memes sont standard et utilisables sur plusieurs systemes, mon code seras portable et meme souvent sans modifier une seulle ligne du code.....

D'autre part en asm, je peux inclure et utiliser des libs c & c++, d'excellents Rad existent pour l'asm et si je donne le meme id à mes objects resources win que sur d'autres plateformes, j'ai juste les resources à refaire (du dessin, quoi...).

Voila pour l'asm pur.

Exemples de rad asm voir : http://radasm.visualassembler.com/

En ce qui concerne mélanger l'asm et delphi c'est souvent utile, voire indispensable dans certains cas...
exemples : manipulation complexes sur bitmaps (en scanline), recherches rapides dans les buffers, Compression/cryptage de données en temps réel etc etc etc....

Meme les codeurs c ont admis que l'asm en ligne est utile...

Imaginez le temps qu'il faudrais (meme avec les bon compilos c & delphi de today) pour décompresser un fichier Zip de 2go cryptés PGP avec des routines 100% haut niveau... lol ... on aurais le temps de se faire une belotte notez bien.... Mais je suis pas sur que le boss/client la trouverais bonne...

Bon Coding...

ManChesTer.
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 -
Ça y est, je me rappelle de ce que je voulais dire:
la REUTILISABILITÉ !!!!!!!!!!!!!!!!!!!!!!!!!!
Bon, j' arrête mes conneries.
Les limites à l' optimisation est celle lorsqu' on porte préjudice à la réutilisabilité/compatibilité.
A+
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 -
Ok les gars, je vais rejoindre les propos de DelphiProg en y ajoutant 2 petites choses: si les préocupations d' aujourd' hui etait la vistesse, on aurait pas de Windows Xp avec des boutons en dégradé, ni d' ailleurs, de boutons du tout et on retournerait programmer sans object. Appli DOS quoi ... Bref, tout ça pour dire que, il faut vivre (heu, je veux dire programmer) avec son temps. Je pense que l' ASM c' est + rapide mais faut pas abuser les gars! Je programme toujours en essayant de voir si mon source sera compatible demain. D' ailleurs Delphi .NET (et même Kykix) est un bon exemple: grâce à la VCL de Delphi, on passe une appli vers une autre plateforme sans trop de problème. Bref, j' ai perdu le fil de mon idée, je termine alors en disant Vive Borland! Merci de nous faciliter la vie!!!
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
On dévie subtilement sur un autre sujet, ne faudrait-il pas ouvrir un autre thème de forum ?
L'usage de quelques lignes d'ASM incorporé en "InLine" dans un projet DELPHI ( d'ailleurs DELPHI8 ou D2005 ont ils toujours cela ??? ) pour la frameWork .NET (DOTNET) , voire meme un programme complet en ASM, cela va t il devenir une galère pas possible comme semble le promettre DelphiProg ?
J'EN DOUTE FORTEMENT , et comme indices vite fait glanés sur le Web :
a) pourquoi Microsoft développerait-il une version 64 bits de son assembleur MASM ==> voir masmforum.com
b) par principe fondateur, tous les languages pourront à terme être incorporés dans .NET ( VB, Php, Java , Cobol, Fortran, etc ...)
c) pourquoi le C# ( CSharp ) inclus dans Visual Studio for .NET ( toujours de Bill gates) offre t il la possibilité de faire de l'Assembleur InLine, de manière quasi-identique à delphi ==> instruction _asm { .... }

voir un exemple ici : http://www.codeproject.com/csharp/unmanage.asp

L'influence de la notion de "Code managé" ou non managé , j'attend d'en comprendre les contraintes pratiques...

voir ici une présentation fort claire (et in French) :
> http://www.dotnet-fr.org/documents/andy_faqdotnet_fr.html

je suggère au modérateur d'ouvrir un autre forum sur ce thème.
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24 -
Pour finaliser les propos de aafi, forts passionnants au demeurant, j'ajouterai que l'asm, c'est bien beau, mais vous serez obligés de revoir votre code si vous souhaitez le porter sur la plateforme .Net.
En effet, le code en assembleur est alors qualifié de "code non managé" et votre application ne pourra pas être certifiée compatible pour .Net.
Là où vous aurez réussi à gagner quelques nanosecondes, vous risquez de perdre des heures à réécrire des parties de votre application, histoire de calmer le compilateur de Delphi.
A vous de voir...
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
Derniere contribution, sur les doutes émis sur l' ASM
a) je ne programme plus en ASM depuis belle lurette, mais la connaissance de l'ASM est un plus pour comprendre ( si vous avez suivi un cours de Mécanique Automobile, vous n'êtes pas obligé de mettre les mains dans le cambouis tous les jours, mais vous ne vous ferez pas niquer pas votre garagiste)

b) comme je l'ai dit précédemment , environ la 1/2 des routines de l'unité principale SYSTEM sont écrites en Assembleur ; alors, si c'était "DANGEUREUX" comme le suggère quelqu'un, alors vite mettez votre DELPHI à la poubelle !

c) un programme ou une routine écrite en ASM à l'époque héroique des processeurs 8 bits (Z80) ou 16 bits (Intel 8086) fonctionnera toujours sur votre super-machin ATHLON 64 bits ( sous réserve des "Entrées/Sorties bas niveau" et des "interruptions" )
MAIS l'INVERSE N'EST PAS VRAI !
DELPHI et consorts usent et abusent des instructions sur registres 32 bits ( EAX par exemple), et des super instructions en Virgule Flottante disponibles sur les processeurs récents.
d) faire soi-même quelques lignes d' ASM au sein d'une unité DELPHI, c'est très risqué si on est un gros débutant , en général le résultat est un beau plantage du genre "Violation d'espace mémoire"
e) je n'ai eu l'occasion de faire de l'ASM que 2 ou 3 fois, uniquement pour optimiser des traitements sur des Strings, pour remplacer des boucles du style FOR X=1 to length(MonString) ....
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
Maintenant, j'ajoute mon grain de sel dans le débat d'une autre nature, introduit par les 3 messages de MAURICIO et JINH68.

Totalement d'accord avec eux sur le fait qu'en pratique, dans le codage d'une application tourné vers un utilisateur ( genre applic de gestion : Comptabilité, gestion de Stocks , etc ... ) , on ne se mord pas la queue pour grapiller quelques 10 milli-secondes, là ou l'usager passe son temps à bouger la souris et lire les infos affichées.

Moi, je privilégie systématiquement le CASE OF lorsqu'il s'agit de tester une valeur unique, y compris dès 2 valeurs comme dans cet exemple
CASE Situation_Familiale of
'M' : appliquer une réduction aux personnes mariés ;
'C' : niquer les célibataires ; // un peu d'humour svp
END ;
Trois ans après , votre patron décide qu'il faut ajouter les cas des Divorcés, puis des pacsés (on vient juste de l'inventer ) etc ;..
On rajoute 2 lignes et ça reste d'une lisibilité limpide :
'D' : faire une fleur aux divorcés ;
'P' : faire une demi réduction aux pacsés

mais, comme le dit JINH68, savoir qu'en tout état de cause, le CASE OF reste toujours le plus performant, ça vous met du beaume au coeur !
NOTA : la méthode de MANCHESTER ( Way4 ) n'est utilisable que si vous avez réellement des procédures élaborées et diverses à exécuter.
ce serait à mon sens idiot de faire des procédures pour des cas du style
'M' : If Sexe 'F' then Réduction 70%
else Réduction = 20 % ;
( j'espère qu'il y a une lectrice sympha qui m'enverra une invitation)

et dans cette hypothèse, mieux vaut optimiser les procédures les plus fréquemment utilisées, car ce sont elles qui plomberont la durée totale.

A l'opposé, si votre applic est un Jeu ( genre Jeu d'Echecs) ou de type scientifique (calculs de recherche opérationnelle, astronomie), je crois que ce forum est très utile !
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
Etant en arrêt pour cause d'accident de ski, je suis condamné à bosser sur ce passionant sujet, plutôt que me vautrer devant une Télé stupide ! Donc, en revenant au forum ID 29593, j'y trouve quelques pistes non explorées :
* quelqu'un demande ce qu'il en est si on teste sur un Integer
* un autre se souvient qu'il aurait lu quelque part que Delphi7 ferait de la "Dichotomie" avec un CASE OF , et l'ami JAPEE lui répond que cela lui semble impossible.
Moi aussi, j'aurai répondu idem en 3 secondes, mais en y réfléchissant, je me dis que ce n'est pas aussi idiot , et que nos super ingénieurs de Borland sont bien capables d'avoir fait la chose ...
Donc, dans le prog à JAPEE, je fait une proc "Way1bis" , ou je transforme I en un integer XI, puis fait un CASE XI OF , sur des valeurs non contigües de 0000 à $3B0 ( soit 60 fois 16) , espacées de 16 (au lieu de 1)
Et merveille, je constate qu'il y a bien DICHOTOMIE dans ce genre de cas : DELPHI génére une série de tests genre caractéristiques d'un arbre dichotomique.
Ca débute par 4 tests découpant l'intervalle demi-bas :
IF valeur >= $1E0
IF valeur >= $0F0
IF valeur >= $070
IF valeur >= $030
puis dans chaque rameau final, 3 tests consécutifs du style
IF valeur = $040 ...
IF valeur = $050 ...
IF valeur = $060

Au final, pour 60 cas , le nombre de tests se retrouve etre au plus de 14 tests ( soit 7 tests > et 7 tests = )

le résultat chiffré est assez éloquent :
Moyenne 33 , au lieu de 23 pour le CASE sur 1 byte de la routine JAPEE originale
Variations de 21 à 38 , ce qui est logique, puisque le nombre de tests varie de 2 (dans le meilleur cas = $1E0 à 14 pour les cas les plus éloignés des valeurs dichotomiques)

ce résultat est par ailleurs bien meilleur ( 4 fois environ) que des IF THEN ELSE ( routine Way3 ), ce qui est assez extraordinaire !

Quelqu'un peut il me dire ou / comment UpLoader mon source "JAPEE modifié" ? pour ceux qui veulent l'examiner ?

PS : Je fonctionne sous DELPHI5, et donc ça doit être valable pour les suivants D6 et D7
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
Maurico,

Un code complexe mais ultra bien commenté/documenté est beaucoup + facile à maintenir qu'un code simple et lisible non ou mal documenté/commenté

D'autre part le temps d'excution d'une tache ne dépend pas que de ton code dans les systemes multitaches, donc + tes routines sont obtimisées , moins tu dérange les autres thread/process...

Bon Coding....

ManChesTer.
jinh68
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Statut
Membre
Dernière intervention
1 septembre 2006
-
Oui excuse moi pr la durée :).En fait il y'a effectivement des instructions propres à certaines architectures, mais les instructions de base depuis le 8086 sont acceptées partout.

@+ :)
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 -
Je suis forcément d' accord avec toi quand tu dis que l'on veut en apprendre toujours plus, mais de là à dire que l 'on programme pas pour les utilisateurs ?!
De plus, l' ASM (je m' y connait pas trop) n' est t-il pas dangeureux par son incompatibilité selon le processeur de la machine? Enfin, je n' ai pas dis 10 secondes mais 10 millisecondes. Mais sinon, je suis d' accord pour tout le reste. A+
jinh68
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Statut
Membre
Dernière intervention
1 septembre 2006
-
En fait, tout le monde est d'accord avec toi je pense, mais là n'est pas l'intérêt.

L'optimisation a toujours été un "sport" chez les développeurs et relève d'une compréhension approfondie du fonctionnement d'un processeur.

Donc pour l'utilisateur, aucun intérêt, mais je ne pense pas que tu développes juste pour lui.Après cela dépend bien sûr de ta vision, mais personnellement j'aime toujours en apprendre plus.

Tu dis que 10 secondes n'est rien, mais c'est comme dans tout domaine, la compétition fait avancer les esprits et affûtent les compétences ;).
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 -
Je vais peut-être mettre mon nez dans un débat qui doit être 'fini' maintenant, mais, après avoir lu tous vos commentaires (sauf les lignes de code, je suis pas mazo), il me semble que vous oubliez 2 petites choses qui sont, à mon avis très importantes et qui d' ailleurs, peuvent faire balancer entre le choix du if then etc ... ou d' un case of. (et là, tout le monde se demande ce que ce petit portugais va nous sortir comme connerie).
Donc, de manière générale:
N' oublions pas que, si on veut gagner quelques millisecondes, faut que ça en vaut la peine. Sinon, il faut privilégier la compréhension du code pour de futurs actualisations de celui-ci. Par exemple, imaginons que l' utilisateur clique sur un bouton et que ça va executer un code où l' on va utiliser le système if then else if then else if then else etc ... ou Case Of (d' où toute cette discussion). Disons que ce code fait tout ça en 1 dixieme de secondes à chaque fois que ' utilisateur clique sur le bouton. Qu' est ce qu' on a à f... de quelle est la méthode la plus rapide! Moi, j' ecrirait un Case Of qui est bien plus simple à comprendre, que l'on gagne ou non 10% de rapidité, ça change rien vu que l' execution du code ne fait pas attendre bêtement l' utilisateur.
Admettons maintenant, que la rapidité est primordiale parce que le code dure plusieurs secondes et que l' utilisateur est en train de bouffer le clavier en attendant que le code finisse. Ça va paraitre evident, mais imaginons qu' on fasse un test de ce genre:
if variable = 360 et que ce test a une probabilité d' etre vrai à environ 50% des cas. Alors là, je pense que le Case Of est bon pour la casse à moins qu' on fasse un truc dans ce genre:
If variable = 360
then begin

end
else
Case variable Of
370: begin

end;

etc ...
End;

Dans l' espoir d' avoir apporté un peu de bon sens à tous ces commentaires quelques fois bien compliqué mais qui n' en sont pas moins interessants.
A+ tout le monde.
cs_grandvizir
Messages postés
1237
Date d'inscription
samedi 8 novembre 2003
Statut
Membre
Dernière intervention
3 septembre 2006
10 -
Merci aafi pour toutes ces précisions ;). Je ne voulais pas être caustique avec vous, mais on ne peut pas être performant en tout, surtout avec l'ASM qui est d'un niveau bien plus puissant que Delphi, lequel n'a rien à voir avec ASM. La relecture de 29593 et de 393257 est intéressante, c'est pour cela que ça se tient très bien...
bundyboss
Messages postés
33
Date d'inscription
mardi 24 juin 2003
Statut
Membre
Dernière intervention
3 mars 2005
-
En fait aafi le debat d'ici découle directement de l'autre lien que tu donnes.. Seulement, ici on est face a du concret via le code.
Merci a Manchester pour cette nouvelle méthode qui repond d'autant mieux a mon problème de base!
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
SUITE ... SUITE ....
( si je vous emm... dites le .... )

en tripatouillant le code à JAPEE, dans la routine WAY1 , amusez vous à supprimer quelques valeurs ( en les mettant en commentaires ) , ou en les énumérant dans un autre ordre ; l'examen de la fenetre CPU montre que ca ne change rien au principe.

par contre si vous supprimez plus de 52 valeurs ( en en laissant moins de 8 ) , alors vous voyez le code assembleur changer.

je modifie donc mes conclusions ainsi :
* ce n'est ni l'ordre d'énumération, ni la présence de discontinuités , qui dirige le compilateur DELPHI.
* DELPHI semble, au final, déterminer le nombre d'items dans le CASE , et il génére :
> soit l'équivalent de IF THEN ELSE lorsqu'il y a seulement 1 à 7 valeurs
> soit la méthode de la Table d'Adressage, pour 8 et plus.

j'en déduit que les ingénieurs de BORLAND ont soigneusement chronométré les routines, et qu'ils considérent que la table d'adressage équivaut au temps processeur pris par environ 7 IF THEN
ET L'ON RETROUVE ICI LE RATIO EXPERIMENTAL du programme à JAPEE . CQFD !!!
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
SUITE ........
Je viens de tester le programme de JAPEE , fort agréable au demeurant , mes résultats pour 1.000.000 boucles ( avec un vieux CP 660 Mhz ) :
CASE = 23
IF THEN = 237
ceci est logique, puisque les IF THEN s'éxécutent tous , dans tous les cas , donc 60 "IF THEN"
ceci signifie , en gros, que le "CASE OF " équivaut à environ 6 instructions "IF THEN" en termes de rapidité

IF THEN ELSE = 128 *
ceci est aussi logique, puisque le "ELSE" permet de splitter en moyenne 30 des comparaisons sur les 60
( 128 = environ la moitié de 237 )

ARRAY = 12 : donc 2 fois plus rapide que le CASE

l'examen du code CPU montre que l'on gagne à chaque fois l'équivalent du fameux JMP dword prt .....

puisque l'on fait seulement
MOV eax,[eax*4 + MyProcs]
CALL eax

dans tous les cas ( les 4 Way1 à Way4 ) , il y a toujours un "CALL" ( appel à la routine RIEN )

cette facon de faire est certainement la plus élégante , la plus rapide, et la plus insensible à la probabilité ( cas les plus fréquents et les plus rares ) ; je viens de la découvrir, car je n'avais jamais eu l'occasion de la pratiquer dans mes applications. MERCI JAPPEE !!!
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
les commentaires de Grand Vizir m'ayant titillé et motivé ( amicalement bien sur) , ja'i pris une heure ou deux pour approfondir le sujet
a) il y a un deuxième forum sur un thème identique , à savoir n° ID 393257 "case of VS if then "
( celui ou nous sommes étant le ID 29593)

b) vous y trouverez aussi un commentaire parlant d'assembleur , fait par KENAVO, assez similaire au mien.

c) Grace à GrandVizir , je viens de m'apercevoir que mes certitudes quant au CASE OF ne sont plus totalement vraies avec les DELPHI récents. Voici ce que j'ai constaté sous DELPHI 5 professional ( je n'ai pas les suivants)

en résumé , CELA DEPEND DE ....
** si votre CASE OF énumére des valeurs consécutives , comme dans le cas proposé ( CASE XX Of ... toutes les valeurs de 1 à 50 par exemple ) , alors ce que je dis est vrai ( passage par une table d'adressage)

** si votre CASE OF n'énumère que quelques valeurs, discontinues , alors le compilateur génére en réalité l'équivalent d'autant de IF THEN ELSE que de cas, avec une petite optimisation
exemple :
CX : char
case CX of
'B' : faire ceci ;
'J' : faire cela ;
'L' : faire autre chose ;
etc ...
end ;
l'optimisation consiste à ne charger qu'1 seule fois la donnée ( ici CX ) dans le registre A ( ou AX ou EAX ) , puis par un jeu subtil de SUBtract ou Add , de tester simplement avec ZERO ( instruction JZ Jump si zero )

Or, dans la pratique d'une vraie application, les cas que l'on teste ne sont que rarement des valeurs en séquence continue.
CONCLUSION : dans la pratique, l'écart de performance reste en faveur du CASE OF , mais l'écart devrait etre beaucoup moins important que celui constaté dans le cas d'école faisant l'objet du forum
par contre, la clarté de lecture d'un source en CASE OF est limpide, alors que des IF THEN ELSE imbriqués deviennent vite illisibles.

d) GrandVizir me demande comment je fais pour voir cela :
il est inutile de "Désassembler"
deux possibilités :
** allez dans ..\DELPHI\SOURCE\RTL\SYS\
vous y trouverez plein de modules en SOURCE, la plupart en ASM ( par exemple OPENFILE.ASM ) et d'autres en Pascal , les 2 principaux étant
SYSTEM.PAS et SYSUTILS.PAS
par exemple SYSTEM.PAS contient des dizaines de routines écrites en Assembleur, par exemple
_COPY ( utilisé par Copy(STR,pos , long) ) )
ou _POS ( utilisé dans pos('GrandVizir' , Message) )

** quand vous exécutez votre projet dans l' IDE ( via la touche <F9> par exemple ), mettez au préalable un POINT d'ARRET ( BreakPoint in english ) sur la ligne CASE .. OF
puis lors de l'arret, examinez le code assembleur en ouvrant la Fenetre de DEBOGUAGE "CPU" : vous y voyez tout le code ASM généré à proximité de votre CASE OF ( avant et après )
ainsi un CASE OF portant sur un Char avec valeurs continus de 'A' à 'K' (par ex.) se traduit par :
4 instructions de préparation ( XOR , MOV , ADD , CMP )
1 JUMP après le END pour les valeurs supérieures à 'K'
et le fameux JUMP indexé indirect , à savoir :
JMP dword ptr [eax*4+Tform1.Button1Click + $12D ]

la Table d'adressage est ici optimisée, elle n'occupe que N fois 4 octets ( N = 11 pour intervalle "A" à "K" )

NOTA : à vérifier pour DELPHI 6 , ou 7 ou 8 ou 2005 !
cs_grandvizir
Messages postés
1237
Date d'inscription
samedi 8 novembre 2003
Statut
Membre
Dernière intervention
3 septembre 2006
10 -
Alors comment vous l'avez sorti votre ASM alors ? Désassembleur ? Parce que c'est bien joli et très intéressant, mais je suis sûr qu'en détaillant un peu, on peut arriver à des choses biens, pour vous et pour les autres.

;)
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
moi non plus je ne pige pas le sens de l'intervention de Mr "GRAND VIZIR" ;
soyons "positif" comme dit la chanson et Mr raffarin !

le débat ici me semble etre :
a) constater la différence de rapidité entre plusieurs façons de programmer
b) d'expliquer le pourquoi.
c) d'approfondir si possible le sujet, en vérifiant les conditions de l'expérimentation.

si Grand Vizir ne veut pas entendre parler d'ASM, alors il n'arrivera jamais à comprendre le "pourquoi"
jinh68
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Statut
Membre
Dernière intervention
1 septembre 2006
-
On va dire que cette intervention est totalement inutile et ne fait pas avancer concrètement le débat, mais on commence à être habitué aux sautes d'humeur du grand vizir :).
cs_grandvizir
Messages postés
1237
Date d'inscription
samedi 8 novembre 2003
Statut
Membre
Dernière intervention
3 septembre 2006
10 -
Votre ASM me rentre par les trous de nez... Et pour japee: «y'a pas écrit La Poste» sur le front de grandvizir. Si y'a pas grand chose à dire, y'a pas de raisons de "raler". Je t'avais mis d'ailleurs un 10 (malgré la pompe). Et si japee s'amuse à étiquetter ses petits camarades de préjugés virtuels, alors je répond modestement :
asm
JNE japee pas content
JMP Coucou
@Coucou:
ECHO On retourne au code source
end
Ca fait franchement pitié ce petit morceau de détresse, mais l'ASM en overdose, ça fait souvent mal... pas à se rendre malade quand même ?
aafi
Messages postés
24
Date d'inscription
mardi 8 février 2005
Statut
Membre
Dernière intervention
12 janvier 2011
-
Mes souvenirs de vieux programmeur en ASSEMBLEUR, et DELPHI depuis la version 1, me font supposer que toute la différence est dans la traduction en language machine, donc des instructions générées, mais normalement à mon avis les options d'OPTIMISATION (*)ne devraient avoir que peu d'effet ( leur role essentiel est de conserver dans les "registres" du processeur les varaibles de tyep CHAR, BYTE, INT qui serviront un peu plus loin dans le code).
Pour faire simple, disons que un CASE sur un CHAR ou BYTE, donc sur une donnée ne pouvant prendre que 256 valeurs de 0 à 255, pourrait se traduire en language machine par :
* un chargement de registre 16 bits , tel que BX
* une mulplication par 2 (en pratique un décalage 1 bit à gauche)
* un JUMP indirect indexé par BX, via une table mémoire des adresses des blocs d'instructions à exécuter
(toutes les valeurs ELSE conduisant au meme code)

ces 3 types d'instructions sont parmi les instructions les plus rapides du jeu INTEL ( 1 à 5 cycles d'horloge)
donc pas étonnant qu'un CASE soit :
a) hyper rapide
b) ayant un temps indépendant de la valeur à tester

L'inconvénient est que la table d'adressage ci-dessus (512ou 1024 octets) consomme de la mémoire , très inutilement lorsque le nombre de valeurs intéressantes est faible ( CASE X of 1 : .... ; 12 : ..... ; 45 : .... end ; )

Des méthodes dérivées de celle-ci, et plus sophistiquées , sont probablement utilisées par Borland , surtout pour les CASE sur des SMALLINT ou plus ( INTEGER , WORD , ... )

De toute facon, Borland , depuis le TURBO PASCAL, est un maitre en optimisation de code ( mais pas toujours hélas, certaines fonctions , sur les STRINGS par exemple, ne sont pas les plus géniales .. )

Enfin, pour les maniaques de la montre atomique, pensez qu'il y a plein de détails à respecter pour pouvoir comparer sans déviation deux routines, surtout sous un OS multitaches ( WinXP / NT ) , et surtout depuis les processeurs genre P4 avec 512 KO ou plus de mémoire cache de 1er niveau, et l'anticipation des instructions !


un vieux de la vieille !
******************

NOTA (*) : sauf celles relatives à la génération de données de DEBUGGING (Debug SYMBOLIQUE) , car celle-ci rajoutent des instructions machines un peu partout dans le code.
japee
Messages postés
1709
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
15 novembre 2019
1 -
Delphiprog > Merci pour le 10/10. Je le partage avec l'ensemble des personnes qui participent à ce débat passionnant, et qui le méritent au moins autant que moi.

C'est un des ces moments rares où l'on se sent une communauté qui, dans sa diversité, se retrouve dans une même passion : la belle programmation en Delphi.

Kenavo et ManChesTer > lol, on a pas fini de se "prendre la tête" (dans le bon sens du terme) sur tout ce que vous avez amené au débat, c'est vraiment très intéressant.

Je vérifie la maj qui incorpore la méthode "array" proposée par Manchester et je la poste.

Bonne prog' à tous !
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
lol kenavo c'etais un concours ?
en fait moi j'utilise cette astuce ds un autre style :

Type TRoutine = record
Params : Array of TvarRec;
Name : String;
Adress : Pointer;
Result : TvarRec;
end;

var mesroutines : Array of Troutine;

...

CallRoutine(MesRoutines[j]);
Resultat=MesRoutines[j].Result;

...

Il vous reste a imaginer le code des ... et celu de callroutine et vous saurez comment apeler fonctiopns et procedures delphi via leur nom (string)
C'est super rapide et ca facilite grandement l'interprétation par exemple de lignes irc ou de code rtf &co....

Bon Coding....

ManChesTer.
cs_Kenavo
Messages postés
756
Date d'inscription
vendredi 21 mars 2003
Statut
Membre
Dernière intervention
1 octobre 2009
1 -
Salut tout le monde,

Pour voir les différences entre byte et DWord il faut contruire le projet sans l'optimisation du code (dans les options du compilateur). Toutes les méthodes "souffrent" de la non optimisation. Puisque tu aimes comparer, Japee, fais donc l'essai !

Par contre, en comparant les codes assembleur générés par le code de ManChesTer et le case of, il y a une différence qui apparait, c'est que le code de ManChester ne vérifie pas si le paramètre est bien dans les limites [0..59].
La prudence voudrait que l'on écrive :
if i in [0..59] then MyProcs[i];
ce qui ne ralentit quasiment pas les performances, surtout si le code est optimisé à la compilation !

C'est là d'ailleurs une différence essentielle entre case of et if : case verifie avant que le paramètre appartient bien à l'intervalle, alors que if teste toutes les comparaisons sans "réféchir"
Fais tourner ta boucle de 0 à 60, tu verras la dernière ligne est explicite !

Euh, alors, le vainqueur est ManChesTer ! Bravo !


Ken@vo
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24 -
C'est rare mais ça m'arrive quand même : je mets 10/10.

Pourquoi ?
1: parce que ce code source et les débats qu'il suscite valent largement un tutorial

2: parce que le code a été soigné malgré la simplicité des processus mis en oeuvre

3: les explications et la présentation sont irréprochables, tant par leur contenu que par leur absence de fautes d'orthographe

Et comme ce qui est rare est cher, alors ça mérite largement un 10.
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24 -
Erratum :
Au lieu de : Alors que le if then saute à la fin de la procédure après exécution de "Rien"

il faut lire :
Alors que le "if ... then ... else" saute à la fin de la procédure après exécution de "Rien"
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24 -
Excellentes démonstrations.
Pour ceux qui sont moins courageux, que donnerait :

1- avec une structure case : "case i of 0..59" au lieu de faire de multiples cases qui dirigent tous vers 'Rien" ?

2- avec la structure "if then" : que donnerait
for j := 0 to MaxBoucle do
begin
if i in [0.. MaxBoucle] then Rien;

au lieu de :
for j := 0 to MaxBoucle do
begin
if i = 0 then Rien;
if i = 1 then Rien;
...
Que le "if then" soit moins rapide est évident puisque le test est effectué pour chacune des conditions même lorsque la condition est remplie dès "if i = 0". Alors que le if then saute à la fin de la procédure après exécution de "Rien".

A chacun de mettre en pratique ces excellents conseils. En espérant qu'on ne verra plus trainer des codes du genre :
if a < 0 then ...
if a = 0 then ...
if a > then ...
Dans de grosses boucles, ça peut faire une énorme différence de performances au final.
Alors, à tous ceux qui parlent d'optimiser leur code, je dis : lisez bien le code de Japee et les remarques des membres ci-dessus et faites attention la prochaine fois que vous parlerez d'optimisation.

Bravo et merci Japee. Il fallait que quelqu'un le fasse. Tu l'as fait et nous t'en remercions.
japee
Messages postés
1709
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
15 novembre 2019
1 -
Résultats avec une boucle 0 à 50 000 000.

On a maintenant :

case of (1), if then (2), if then else (3), array avec i passé en byte (4), array avec i passé en DWord (5).


i 1 2 3 4 5
_______________________________________________________
0: | 1035 | 6840 | 995 | 866 | 865 |
1: | 1035 | 6675 | 1115 | 870 | 870 |
2: | 1075 | 6760 | 1245 | 865 | 870 |
3: | 1035 | 6730 | 1325 | 870 | 865 |
4: | 1080 | 6661 | 1409 | 870 | 865 |
5: | 1076 | 7525 | 1490 | 870 | 870 |
6: | 1030 | 6750 | 1570 | 870 | 870 |
7: | 1075 | 6680 | 1615 | 870 | 870 |
8: | 1030 | 6695 | 1740 | 865 | 870 |
9: | 1035 | 6635 | 1820 | 870 | 870 |
10: | 1075 | 6760 | 1900 | 870 | 870 |
11: | 1035 | 6675 | 1986 | 865 | 870 |
12: | 1075 | 6640 | 2025 | 870 | 870 |
13: | 1075 | 7410 | 2110 | 870 | 865 |
14: | 1035 | 6645 | 2235 | 870 | 870 |
15: | 1075 | 6560 | 2360 | 865 | 870 |
16: | 1035 | 6625 | 2485 | 865 | 870 |
17: | 1035 | 6675 | 2605 | 870 | 870 |
18: | 1075 | 6745 | 2730 | 871 | 869 |
19: | 1035 | 6725 | 2815 | 865 | 870 |
20: | 1071 | 6805 | 2895 | 870 | 870 |
21: | 1075 | 7630 | 2975 | 870 | 870 |
22: | 1035 | 6790 | 3060 | 865 | 870 |
23: | 1075 | 6715 | 3105 | 865 | 870 |
24: | 1035 | 6700 | 3225 | 865 | 870 |
25: | 1035 | 6775 | 3305 | 870 | 870 |
26: | 1075 | 6785 | 3390 | 870 | 870 |
27: | 1035 | 6720 | 3475 | 870 | 865 |
28: | 1075 | 6755 | 3515 | 865 | 865 |
29: | 1075 | 7656 | 3599 | 865 | 865 |
30: | 1035 | 6720 | 3720 | 870 | 870 |
31: | 1075 | 6770 | 3845 | 870 | 870 |
32: | 1035 | 6790 | 3970 | 870 | 865 |
33: | 1030 | 6765 | 4095 | 870 | 870 |
34: | 1075 | 6730 | 4215 | 865 | 870 |
35: | 1035 | 6975 | 4305 | 865 | 871 |
36: | 1074 | 6705 | 4380 | 870 | 870 |
37: | 1075 | 7520 | 4465 | 870 | 870 |
38: | 1030 | 6740 | 4550 | 865 | 870 |
39: | 1076 | 6839 | 4585 | 865 | 870 |
40: | 1035 | 6615 | 4715 | 871 | 869 |
41: | 1035 | 6695 | 4795 | 870 | 870 |
42: | 1031 | 6850 | 4880 | 870 | 870 |
43: | 1075 | 6785 | 4970 | 865 | 870 |
44: | 1036 | 6869 | 5005 | 870 | 865 |
45: | 1075 | 7550 | 5085 | 870 | 870 |
46: | 1035 | 6710 | 5210 | 870 | 870 |
47: | 1075 | 6730 | 5335 | 870 | 870 |
48: | 1030 | 6755 | 5460 | 865 | 865 |
49: | 1030 | 6705 | 5580 | 870 | 870 |
50: | 1095 | 6894 | 5705 | 870 | 870 |
51: | 1030 | 6810 | 5765 | 866 | 869 |
52: | 1080 | 6675 | 5835 | 870 | 865 |
53: | 1035 | 7555 | 5955 | 870 | 870 |
54: | 1035 | 6775 | 6080 | 865 | 870 |
55: | 1035 | 6680 | 6155 | 870 | 870 |
56: | 1035 | 6645 | 6205 | 865 | 865 |
57: | 1035 | 6730 | 6330 | 870 | 870 |
58: | 1030 | 6745 | 6450 | 870 | 870 |
59: | 990 | 6685 | 6410 | 870 | 870 |
|_________|_________|_________|_________|_________|
| 1051 | 6829 | 3736 | 868 | 869 |

La différence entre i en Byte ou i en DWord est statistiquement inexistante (j'ai fait d'autres tests).

Je pense qu'il doit en être de même avec case of, if then et if then else, mais je vérifierai.

A bientôt pour la mise à jour qui incorporera la procedure avec array et une petite fonctionnalité qui permet de récupérer les résultats dans un fichier txt (vous croyez tout de même pas que je me suis tapé tout ce tableau à la main, si ? :P
jinh68
Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Statut
Membre
Dernière intervention
1 septembre 2006
-
Svp arrêtez les tests consécutifs et observez ce qui se passe en asm pr le case dans ce cas la ;).

Delphi gruge !!!
japee
Messages postés
1709
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
15 novembre 2019
1 -
grandvizir> je t'ai trouvé plus accomodant que d'habitude avec mon code. T'es pas malade, au moins... ;)

Sérieusement, je ne pense pas que l'affichage dans les Memo pénalise le test, car il se fait en dehors des boucles.

J'ai précisément fait attention de n'interférer aucunement par un affichage quelconque de la progression etc... pendant la boucle de chaque test.

Pour le reste, faut voir...
japee
Messages postés
1709
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
15 novembre 2019
1 -
En attendant la mise à jour de mon code pour pouvoir comparer cette pléthore d'astuces, voici les résultats de la comparaison des 3 premières méthodes + celle à ManChesTer dans une boucle de 0 à 50 000 000.
Dans l'ordre :

case of (1), if then (2), if then else (3), array (4).

i 1 2 3 4
_________________________________
0: | 535 | 6285 | 412 | 290 |
1: | 580 | 6165 | 495 | 290 |
2: | 540 | 6030 | 580 | 290 |
3: | 540 | 6130 | 615 | 295 |
4: | 575 | 6170 | 745 | 290 |
5: | 535 | 6155 | 825 | 290 |
6: | 580 | 6110 | 910 | 290 |
7: | 580 | 7125 | 990 | 290 |
8: | 540 | 6135 | 1035 | 290 |
9: | 580 | 6240 | 1120 | 290 |
10: | 535 | 6265 | 1240 | 290 |
11: | 535 | 6070 | 1365 | 290 |
12: | 580 | 6210 | 1490 | 290 |
13: | 535 | 6255 | 1610 | 290 |
14: | 580 | 6280 | 1735 | 290 |
15: | 580 | 7095 | 1820 | 290 |
16: | 535 | 6065 | 1900 | 290 |
17: | 580 | 6230 | 1985 | 290 |
18: | 540 | 6120 | 2066 | 285 |
19: | 540 | 6020 | 2110 | 290 |
20: | 580 | 6270 | 2230 | 290 |
21: | 540 | 6075 | 2315 | 290 |
22: | 580 | 6210 | 2401 | 289 |
23: | 580 | 6940 | 2480 | 290 |
24: | 540 | 6190 | 2520 | 290 |
25: | 575 | 6160 | 2605 | 285 |
26: | 535 | 6110 | 2725 | 290 |
27: | 540 | 6235 | 2855 | 290 |
28: | 580 | 6190 | 2975 | 291 |
29: | 535 | 6260 | 3105 | 290 |
30: | 575 | 6230 | 3225 | 290 |
31: | 580 | 7035 | 3310 | 291 |
32: | 534 | 5995 | 3395 | 290 |
33: | 580 | 6225 | 3470 | 290 |
34: | 540 | 6075 | 3555 | 291 |
35: | 539 | 6225 | 3595 | 290 |
36: | 580 | 6130 | 3720 | 290 |
37: | 540 | 6245 | 3805 | 290 |
38: | 575 | 6278 | 3885 | 290 |
39: | 575 | 6925 | 3970 | 290 |
40: | 535 | 6145 | 4010 | 290 |
41: | 980 | 6295 | 4090 | 290 |
42: | 540 | 6325 | 4215 | 290 |
43: | 580 | 6225 | 4345 | 290 |
44: | 570 | 6305 | 4465 | 290 |
45: | 540 | 6120 | 4590 | 290 |
46: | 580 | 6190 | 4715 | 290 |
47: | 540 | 7015 | 4795 | 290 |
48: | 580 | 6130 | 4880 | 290 |
49: | 540 | 6305 | 4965 | 290 |
50: | 540 | 6145 | 5010 | 290 |
51: | 535 | 6070 | 5085 | 290 |
52: | 535 | 6260 | 5210 | 290 |
53: | 535 | 6276 | 5335 | 290 |
54: | 535 | 6130 | 5390 | 290 |
55: | 580 | 7130 | 5460 | 290 |
56: | 535 | 6150 | 5585 | 290 |
57: | 575 | 6155 | 5706 | 289 |
58: | 540 | 6175 | 5785 | 290 |
59: | 456 | 6169 | 5750 | 290 |
|______|_______|______|______|
| 561 | 6281 | 3110 | 290 |


Bluffant, n'est-il pas ?

Remarquable, la régularité des temps obtenus par la méthode array...

Si ça continue, les gars, il va falloir que j'envisage la création dynamique de l'ensemble Label, Memo, Edit servant à recueillir les résultats. J'ai du mal à suivre la cadence, moi... :(
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
heuu kenavo, tu change rien a ma technique, c normal que si tu utilise un dword en entrée c'est plus rapide, delphi 32 est en 32bits dword aussi.

Bon Coding....

ManChesTer.
cs_Kenavo
Messages postés
756
Date d'inscription
vendredi 21 mars 2003
Statut
Membre
Dernière intervention
1 octobre 2009
1 -
La course à la vitesse continue :

procedure TForm1.Way2Array(i: DWord);
const MyProcs : Array [0..59] of Tprocedure =
(Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien);
var
j : LongInt;
h : Word;
begin
h := GetTickCount;
for j := 0 to MaxBoucle do
MyProcs[i];
h := GetTickCount - h;
Memo5.Lines.Add(IntToStr(h));
end;


Kenavo (d'après ManChesTer)
cs_grandvizir
Messages postés
1237
Date d'inscription
samedi 8 novembre 2003
Statut
Membre
Dernière intervention
3 septembre 2006
10 -
Japee: ce code est... il est... pouf... Comment dire ? Peut-être très sûrement génial pour l'évolution des connaissances sur Delphifr (sans aucune ironie cachée!).

Mais pour l'exécution des tests, il faut prendre toutes ses précautions:
1) Générer les EXE dans différentes versions de Delphi.
2) Rebooter le PC pour vider la RAM et surtout pour killer le "Delphi's memory thread effect" (si je peux m'exprimer ainsi, car il ne faut pas croire, Delphi gruge la RAM)
3) Stocker les résultats dans des TStringList, car les affichages du mémo sont du temps de perdu et fausse l'analyse.
4) Threader à haute priorité (la plus haute, au même niveau que les threads multimédia) les 3 procédures afin de leur donner le flux maximal et moins indépendant d'autres processus

Au passage, 3 fichiers inutiles dans le ZIP ;)

Remarque à propos du ELSE IF avec D5. Nous avons la suite suivante:
206 - 214 - 253 - 272 - 301 - 320- 341 - 353 - 385 - 392 - 423 - 438 - 465 - 476 - 508 - 516 - 550 - 554. Elle est à peut près linéaire pour les 20 premières tentatives successives et la modélisation donne "T = 21 * x + 209", où T est exprimé en ms, et où X représente la x-ième tentative. Donc elle est certes rapide, mais nécessairement facteur de ralentissement du PC.

Je donne mes tests (même si vous en avez déjà faits). Je choisis "10 millions" pour minimiser statistiquement les écarts liés par exemple à des co-traitements du processeur, tels un mouvement de souris, une activité multimédia ou un scan antivirus, et surtout parce que je n'ai pas que ça à faire non plus. On essaye de travailler dans un petit environnement clos pour calmer le jeu.
D3: 58 - 273 - 158
D5: 58 - 277 - 157
D7: 58 - 274 - 158
Après avoir joué successivement avec les versions, je reboote et lance le teste D7 et: 58 - 275 - 156.

Là je conclus que les tests sont cohérents et que D3 est mon ami... Où est donc l'évolution apportée par Delphi 7 ?? Hein... A moins que je ne confonde avec quelque chose d'autre.

Reste à voir deux choses:
1) L'enchaînement des procédures a-t-elle une importance ?
2) Que dire du "Case avec des string" par rapport à des IF ? Quelqu'un avait fait un code sur Delphifr (je ne donne pas de nom, mais je crois quand même me souvenir qui c'était).

En conclusion, Japee va pouvoir nous implémenter tout ça, histoire de voir ce que ça donnera.
japee
Messages postés
1709
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
15 novembre 2019
1 -
Manchester> Remarquable !

Moyenne des résultats avec Maxboucle = 10 000 000 :

case of: 226
if then: 1656
if then else: 757
array: 178

Verdict: encore plus performant que case...of, et légèrement moins de variations quelle que soit la valeur de la variable.

Stupéfiant...
cs_ManChesTer
Messages postés
378
Date d'inscription
vendredi 20 octobre 2000
Statut
Modérateur
Dernière intervention
11 décembre 2013
-
essaye ca :
procedure TForm1.Way1Array(i: Byte);
const MyProcs : Array [0..59] of Tprocedure =
(Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,
Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien,Rien);
var
j : LongInt;
h : Word;
begin
h := GetTickCount;
for j := 0 to MaxBoucle do
MyProcs[i];
h := GetTickCount - h;
Memo4.Lines.Add(IntToStr(h));
end;

Bon Coding....

ManChesTer.
cs_Kenavo
Messages postés
756
Date d'inscription
vendredi 21 mars 2003
Statut
Membre
Dernière intervention
1 octobre 2009
1 -
Mauricio, en gros : Oui ! Mais je me méfie de ton etc...

Je rapelle que pour marcher aussi bien, il faut que les coefficients de l'instruction case soient consécutifs. Sinon...

Et puis, il faut que j'avoue : j'ai repéré un genre de dichotomie dans une instruction case !...

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 -
Je suppose que ces résultats sont similaires qques soit la nature de la comparaison char/byte/integer/word/int64 etc ...
cs_Kenavo
Messages postés
756
Date d'inscription
vendredi 21 mars 2003
Statut
Membre
Dernière intervention
1 octobre 2009
1 -
Salut,

Après quelques essais - et avoir rajouté un graphe des résultats (avec l'excellent TGraphXY) - je peux dire :
1 - que les résultats sont ceux que j'attendais
2 - entre D4 (pro) et D7 (perso) il n'y a pas de différence significative du code généré pour ce source.
3 - que - sur ce source - cocher ou non la case optimisation n'a pas d'influence (il fallait vérifier ! on ne sait jamais)

... et je rajouterais que je ne vois pas bien comment utiliser le principe de dichotomie dans une instruction case of. A moins de vouloir compliquer !

... et merci, Ô Japee, de ne pas avoir laissé les résultats de nos divagations théoriques à l'état de rumeur non vérifiée. Un petit (?) code valant mieux parfois qu'un long discours.

Ken@vo
jmp77
Messages postés
1119
Date d'inscription
lundi 4 février 2002
Statut
Membre
Dernière intervention
4 octobre 2006
4 -
Nickel je viens de compiler avec Delphi 6 et le résultat est sans appel :
Case : 14ms
If then : 140 ms
If then else : 75 ms.

Une grande victoire du case qui me rassure.

Encore merci à toi pour ce superbe programme de test. Et ouais je pense que ca serait sympa d'en faire une machine a tester c'est toujours tres utile.

Au fait note finale : 10/10 pour moi.
japee
Messages postés
1709
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
15 novembre 2019
1 -
Hello, ni69 !

Case of vainqueur par KO, semble-t'il... ;)


Salut, JMP !

Ben, j'ai Delphi 4 Pro, mais ça va peut-être dépendre de la version de Delphi sous laquelle tu vas compiler, non ? ou je dis une bêtise... ;)

Sinon je me suis dit aussi, après coup, qu'en adaptant éventuellement un peu le code et l'interface, on peut concevoir un programme qui deviendrait une sorte de "machine à tester" pour comparer deux fonctions dont on se demande quelle est la plus efficace.
jmp77
Messages postés
1119
Date d'inscription
lundi 4 février 2002
Statut
Membre
Dernière intervention
4 octobre 2006
4 -
Super initiative japee je testerais cela demain.

Pourrais tu juste préciser la version de delphi que tu as? Car je me souviens d'une reponse qui disait que a partir de delphi 7 les case of etait gérée pas dichotomie alors a verfier.

JMP77.
ni69
Messages postés
1418
Date d'inscription
samedi 12 juin 2004
Statut
Membre
Dernière intervention
5 juillet 2010
8 -
C'est un bon condensé Bravo Japee ! ;)
La palme d'or revient indéniablement à "case of"... Ca me rassure : j'ai toujours pensé ça :P