begin process at 2012 02 11 15:03:24
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Exécution

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

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


 Information sur la source

Note :
10 / 10 - par 4 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Exécution Classé sous :case, if, then, else, comparer Niveau :Débutant Date de création :17/02/2005 Date de mise à jour :20/02/2005 02:05:13 Vu / téléchargé :15 344 / 581

Auteur : japee

Ecrire un message privé
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (60)
Ajouter un commentaire et/ou une note


 Description

Cliquez pour voir la capture en taille normale
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 !

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

20 février 2005 00:44:18 :
Rajouté la procedure de Manchester dans le quatrième memo.
20 février 2005 02:05:13 :
maj mineure (capture)

 Sources du même auteur

Source avec Zip Source avec une capture DEPLACER LES ITEMS D'UNE LISTBOX VERS UNE AUTRE PAR DRAG AND...
Source avec Zip Source avec une capture DÉMINEUR UTILISANT UNE TDRAWGRID ET AVEC LEQUEL ON PEUT TRIC...
Source avec Zip Source avec une capture SIGNIFICATION DES CODES D'ERREUR DE L'API WIN32 - UTILISATIO...
Source avec Zip Source avec une capture CONVERSION LITTÉRALE D'UN NOMBRE ENTIER OU FLOTTANT
Source avec Zip Source avec une capture TPULSEBUTTON - RÉPÉTITION PROGRESSIVE D'UN EVENT PENDANT ONK...

 Sources de la même categorie

Source avec Zip Source avec une capture INTERPRETEUR DE LANGAGE PERSONNALISABLE BIS par barbichette
Source avec Zip Source avec une capture INTERPRETEUR DE LANGAGE PERSONNALISABLE par barbichette
Source avec Zip Source avec une capture INTERCEPTION ARRET WINDOWS par dc46
Source avec Zip FREE PASCAL - EXERCICE AVEC TABLE DE HACHAGE par chatmar
Source avec Zip LE CRIME PARFAIT par Caribensila

 Sources en rapport avec celle ci

Source avec Zip TRIER DU GREC DANS UNE APPLI EN CODE LOCAL FRANÇAIS. par fricot
Source avec Zip Source avec une capture CALCUL DE CORRELATION ENTRE 2 IMAGES par Nicolas___

Commentaires et avis

Commentaire de ni69 le 17/02/2005 21:25:04

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

Commentaire de jmp77 le 17/02/2005 21:32:32

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.

Commentaire de japee le 17/02/2005 22:35:42 administrateur CS

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.

Commentaire de jmp77 le 18/02/2005 09:40:30

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.

Commentaire de Kenavo le 18/02/2005 11:03:10

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

Commentaire de MAURICIO le 18/02/2005 11:13:11 administrateur CS

Je suppose que ces résultats sont similaires qques soit la nature de la comparaison char/byte/integer/word/int64 etc ...

Commentaire de Kenavo le 18/02/2005 12:02:40

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

Commentaire de ManChesTer le 18/02/2005 16:49:14 administrateur CS

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.

Commentaire de japee le 18/02/2005 17:19:37 administrateur CS

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...

Commentaire de grandvizir le 18/02/2005 20:38:42

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.

Commentaire de Kenavo le 18/02/2005 20:44:22

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)

Commentaire de ManChesTer le 18/02/2005 21:08:37 administrateur CS

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.

Commentaire de japee le 18/02/2005 21:43:13 administrateur CS

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...  :(

Commentaire de japee le 18/02/2005 21:54:01 administrateur CS

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...

Commentaire de jinh68 le 18/02/2005 22:56:48

Svp arrêtez les tests consécutifs et observez ce qui se passe en asm pr le case dans ce cas la ;).

Delphi gruge !!!

Commentaire de japee le 18/02/2005 23:08:22 administrateur CS

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

Commentaire de Delphiprog le 19/02/2005 10:30:36 administrateur CS

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.

Commentaire de Delphiprog le 19/02/2005 10:32:08 administrateur CS

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"

Commentaire de Delphiprog le 19/02/2005 10:37:10 administrateur CS

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.

Commentaire de Kenavo le 19/02/2005 11:10:29

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

Commentaire de ManChesTer le 19/02/2005 13:12:50 administrateur CS

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.

Commentaire de japee le 19/02/2005 15:23:26 administrateur CS

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 !

Commentaire de aafi le 23/02/2005 18:06:26

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.

Commentaire de grandvizir le 26/02/2005 21:56:59

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 ?

Commentaire de jinh68 le 27/02/2005 05:47:53

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 :).

Commentaire de aafi le 27/02/2005 11:23:24

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"

Commentaire de grandvizir le 01/03/2005 09:30:09

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.

;)

Commentaire de aafi le 02/03/2005 21:29:31

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 !

Commentaire de aafi le 02/03/2005 22:20:18

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 !!!

Commentaire de aafi le 02/03/2005 22:59:28

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 !!!

Commentaire de bundyboss le 03/03/2005 01:21:29

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!

Commentaire de grandvizir le 03/03/2005 12:45:44

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...

Commentaire de MAURICIO le 03/03/2005 15:43:55 administrateur CS

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.

Commentaire de jinh68 le 03/03/2005 15:55:04

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 ;).

Commentaire de MAURICIO le 03/03/2005 17:54:57 administrateur CS

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+

Commentaire de jinh68 le 03/03/2005 18:25:48

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.

@+ :)

Commentaire de ManChesTer le 03/03/2005 18:35:12 administrateur CS

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.

Commentaire de aafi le 03/03/2005 18:50:58

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

Commentaire de aafi le 03/03/2005 19:20:53

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 !

Commentaire de aafi le 03/03/2005 19:57:25

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) ....

Commentaire de Delphiprog le 03/03/2005 21:23:24 administrateur CS

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...

Commentaire de aafi le 04/03/2005 09:33:23

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.

Commentaire de MAURICIO le 04/03/2005 11:42:05 administrateur CS

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!!!

Commentaire de MAURICIO le 04/03/2005 11:47:23 administrateur CS

Ç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+

Commentaire de ManChesTer le 04/03/2005 15:25:40 administrateur CS

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.

Commentaire de aafi le 04/03/2005 18:44:48

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 !

Commentaire de ManChesTer le 05/03/2005 00:32:56 administrateur CS

aafi,

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

Bon Coding...

ManChesTer.

Commentaire de Delphiprog le 05/03/2005 08:10:44 administrateur CS

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.

Commentaire de aafi le 05/03/2005 09:14:47

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 !

Commentaire de Delphiprog le 05/03/2005 09:40:04 administrateur CS

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.

Commentaire de ManChesTer le 05/03/2005 17:59:21 administrateur CS

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.

Commentaire de ManChesTer le 05/03/2005 18:10:53 administrateur CS

Lol, faut lire CLI pas CLR qui est le runtime en question...

Bon Coding....

ManChesTer.

Commentaire de Delphiprog le 05/03/2005 21:11:11 administrateur CS

"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 ?

Commentaire de aafi le 06/03/2005 09:39:25

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#
******

Commentaire de Delphiprog le 06/03/2005 10:34:13 administrateur CS

aafi : c'est parfait.
rdv sur :
http://www.delphifr.com/forum.v2.aspx?ID=406173
ou encore :
http://tinyurl.com/5yppj

pour la suite des discussions.

Commentaire de grandvizir le 16/03/2005 13:42: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+.

Commentaire de MAURICIO le 16/03/2005 14:35:02 administrateur CS

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 !!!

Commentaire de Kenavo le 16/03/2005 15:19:33

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

Commentaire de MAURICIO le 16/03/2005 16:38:30 administrateur CS

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 : )

Commentaire de aafi le 16/03/2005 20:12:35

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 ......

================

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

[Delphi 5] Problème de compilation et de boucle if [ par Nyio ] Bonjour à tous, Je travail actuellement sous Delphi 5 et deux problèmes me bloquent dans l'avancement de mon projet : [u]Problème 1 :[/u] [code=pas] Ouvrir MS Word, Excel etc en plein ecran [ par lordrt ] Bonjour à tous, J'ai un app en Delphi qui ouvre des documents OLE, ex. Word, Excel, PDF entre autres, mais le probleme est que si la fenetre du docume simplifier conditions [ par JackNUMBER ] Bonsoir une petite question facile, comment "simplifier" ces conditions : [code=pas]for i:= CheckListBox1.Count -1 downto 0 do if CheckListBox1.Chec Pas de rafraichissement des textes dans mes memo après un Read [ par DONALD3D ] Salut, le grand débutant que je suis s'arrache les cheveux sur un truc curieux, mes champs de texte dans les memo prévus ne sont pas raffraichit quan TShiftState de FormKeyDown de la form [ par MohInfo ] Bonsoir à tous lors de l'utilisation de l'évènement FormKeyDown de ma form (FormStyle = fsMDIForm)je veux faire un raccourci clavier pour chaque bout Boucle For qui stoppe au bout de 99 valeurs [ par bouddha69 ] Bonjour, J'avance petit à petit dans ma programmation et je suis presque au bout. Il me reste un petit problème (qui en fait est vraiment embêtant). Fonction qui retourne une autre valeur !! [ par grandyaka54 ] Bonjour à tous, J'ai un problème sur lequel je ne m'explique pas. Ma fonction Crypt(Maintenant, '.cry'); que j'utilise dans la fonction btnCryptageCl arrondir un nombre selon nombre dans une listbox... [ par elt93 ] Bonjour,Je travaille sur un logiciel de calcul ou jaimerais ajouter une fonction arrondir, en dessous se situe une TListBox avec les nombres de 1 à 5 choix radiobutton [ par watrem ] Bonjour voila j'ai installer sur une fiche 2 radiobutton , chaque radio button a pour fonction de ranger des donnees numeriques soit par fichier de 20 Navigateur par onglet [ par frederic6962 ] Bonjour à tous.J'ai créer un navigateur par onglet. J'utilise donc un pagecontrol, un TTabsheet et un webbrowser, le tout créer dynamiquement. J'ai in


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 3,494 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales