Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

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


Information sur la source

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é: 12 002 / 526

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

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

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

Pour les "Membres Club", vous pouvez 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)

Commentaires et avis

signaler à un administrateur
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

signaler à un administrateur
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.

signaler à un administrateur
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.

signaler à un administrateur
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.

signaler à un administrateur
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

signaler à un administrateur
Commentaire de MAURICIO le 18/02/2005 11:13:11

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

signaler à un administrateur
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

signaler à un administrateur
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.

signaler à un administrateur
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...

signaler à un administrateur
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.

signaler à un administrateur
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)

signaler à un administrateur
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.

signaler à un administrateur
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...  :(

signaler à un administrateur
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...

signaler à un administrateur
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 !!!

signaler à un administrateur
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

signaler à un administrateur
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.

signaler à un administrateur
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"

signaler à un administrateur
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.

signaler à un administrateur
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

signaler à un administrateur
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.

signaler à un administrateur
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 !

signaler à un administrateur
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.

signaler à un administrateur
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 ?

signaler à un administrateur
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 :).

signaler à un administrateur
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"

signaler à un administrateur
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.

;)

signaler à un administrateur
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 !

signaler à un administrateur
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 !!!

signaler à un administrateur
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 !!!

signaler à un administrateur
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!

signaler à un administrateur
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...

signaler à un administrateur
Commentaire de MAURICIO le 03/03/2005 15:43:55

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.

signaler à un administrateur
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 ;).

signaler à un administrateur
Commentaire de MAURICIO le 03/03/2005 17:54:57

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+

signaler à un administrateur
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.

@+ :)

signaler à un administrateur
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.

signaler à un administrateur
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

signaler à un administrateur
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 !

signaler à un administrateur
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) ....

signaler à un administrateur
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...

signaler à un administrateur
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.

signaler à un administrateur
Commentaire de MAURICIO le 04/03/2005 11:42:05

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

signaler à un administrateur
Commentaire de MAURICIO le 04/03/2005 11:47:23

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

signaler à un administrateur
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.

signaler à un administrateur
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 !

signaler à un administrateur
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.

signaler à un administrateur
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.

signaler à un administrateur
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 !

signaler à un administrateur
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.

signaler à un administrateur
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.

signaler à un administrateur
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.

signaler à un administrateur
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 ?

signaler à un administrateur
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#
******

signaler à un administrateur
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.

signaler à un administrateur
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+.

signaler à un administrateur
Commentaire de MAURICIO le 16/03/2005 14:35:02

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

signaler à un administrateur
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

signaler à un administrateur
Commentaire de MAURICIO le 16/03/2005 16:38:30

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

signaler à un administrateur
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

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 "Jeu de dames" [ par ptitlog ] Bonjour à tous, je suis inscrit su le site depuis un petit temps étant donné que je viens souvent me ressourcer ici cependant je n'ai encore jamais po pointeurs! [ par Samou85 ] Bonjour à tous!j'ai un tableau de pointeur "T" et et à un moment donné je dois supprimer certaine cases de ce tableau, je voudrais savoir si le fait d lire un fichier et comparer [ par shell13010 ] Bonjour a tous et a toute,je vais vous expliquez mon probleme,alors j'ai un Tbutton  Tmemo et un Tlistbox avec un fichier qui se nomme exemple.txtdonc Lancer une application windows depuis un service DELPHI [ par PourApp000 ] Bonjour,je n'arrive pas, malgrè tous les conseils et exemples que j'ai pu lire, à relancer une application depuis un service. Ma problèmatique est la apparition de point d'interrogation dans text [ par givit ] Bonjour à tous,J'ai deux problèmes. Voici mon premier :Je viens de me rendre compte que dans les résultat de mes différents scripts (forum, moteur de Error E/S 32 sur ecriture et suppresion [ par te56350 ] slt tt le mondej'Ai besoin d'une solution pour mon projet en cour SVPMon projet gère des comptes utilisAteurs Et qu'An j'enregistre des comptes çA fon


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Comparez les prix Nouvelle version

Photothèque Nouveau !



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
Temps d'éxécution de la page : 0,499 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.