IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

[XE] Curiosité sur le For .. IN


Sujet :

Langage Delphi

  1. #1
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut [XE] Curiosité sur le For .. IN
    Voici le code incriminé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    type
      TMonTest = (mt1, mt2, mt3{, mt4, mt5, mt6, mt7, mt8, mt9});
      TMonTests = Set of TMonTest;
    end;
    Puis dans un bouton mettre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    var
      T1 : TMonTests;
      T2 : TMonTest;
      i : integer;
    begin
      i := 0;
      T1 := [mt1, mt3];
      for T2 in  T1 do
      begin
        case T2 of
          mt1: Showmessage('mt1');
          mt2 : Showmessage('mt2');
          mt3 : Showmessage('mt3');
        end;
        Inc(i);
      end;
      Showmessage('boucle :' + IntToStr(i));
    end;
    Explication du phénomène

    - En Exécution :
    Si on exécute le code suivant on a mt1 et Mt3 qui apparaissent via un showmessage et à la fin boucle indique 2.

    -En Pas à pas :
    Chose étrange on passe 8 fois dans la boucle for (si vous placez le point d'arrêt sur le for on est obligé de faire 8 fois F8) mais on ne passera que 2 fois dans le corps de la boucle.

    D'où peut venir se phénomène ?
    Est ce que vous avez ce même phénomène avec d'autres version de delphi ?

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Je n'ai pas Delphi mais C++Builder, je ne peux pas vérifier
    En tout cas, les Iterator ne tourne pas dans le vide en c++

    Possible que cela soit lié à la nature même du for..in qui doit être codé différemment selon le type
    Là c'est une valeur énuméré et un ensemble
    mais for..in fonctionne aussi pour les containers ayant implémenter IEnumerable
    Est-ce qu'un Set of gère IEnumerable via un Helper par exemple ?
    Peut-être que certains F8 correspond au phase de is \ as vers IEnumerable

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    je viens de faire le test sous XE2 en fait c'est codé comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Unit1.pas.37: for T2 in  T1 do
    00511397 8A45FB           mov al,[ebp-$05]
    0051139A 8845F3           mov [ebp-$0d],al
    0051139D C645FA00         mov byte ptr [ebp-$06],$00
    Unit1.pas.38: begin
    005113A1 8A45FA           mov al,[ebp-$06]
    005113A4 3C07             cmp al,$07
    005113A6 770A             jnbe $005113b2
    005113A8 83E07F           and eax,$7f
    005113AB 0FB655F3         movzx edx,[ebp-$0d]
    005113AF 0FA3C2           bt edx,eax
    005113B2 7334             jnb $005113e8
    on a bien 8 itérations de 0 à 7 (cmp al,$07) et à chaque fois il test si le bit "n" est allumé (bt edx, eax). On pourrait écrire sous Delphi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      for Byte(T2) := 0 to 7 do 
        if T2 in T1 then
        begin
          ...
          Inc(i);
        end;
    ce qui explique les 8 boucles alors que i = 2

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Il utilise la taille de Set et pas le nombre d'élément possible !
    Oh ! Ce n'est pas très optimisé !

    Cela voudrait dire que si l'on défini mt1 à mt9 comme on se retrouve avec 9 bit, il passe donc à 2 octet donc 16 itérations ?

    J'allais bientôt faire du Delphi XE2 au lieu de C++
    j'aurais bien eu l'occasion de faire un for i := Low(i) to High(i) do avec i un énumération et une manipulation de Set,
    je crois que je vais conserver ma syntaxe habituelle de D7 finalement !

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Il utilise la taille de Set et pas le nombre d'élément possible !
    Oh ! Ce n'est pas très optimisé !

    Cela voudrait dire que si l'on défini mt1 à mt9 comme on se retrouve avec 9 bit, il passe donc à 2 octet donc 16 itérations ?

    J'allais bientôt faire du Delphi XE2 au lieu de C++
    j'aurais bien eu l'occasion de faire un for i := Low(i) to High(i) do avec i un énumération et une manipulation de Set,
    je crois que je vais conserver ma syntaxe habituelle de D7 finalement !
    avec mt9 la boucle passe à 16 itérations
    si on pousse jusque mt17 il passe à 32

    bref, le calcul est fait à la louche

  6. #6
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    un collège a testé sous D2007 et il a un comportement assez aléatoire sur le nombre d'itération que va faire la boucle.

  7. #7
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    Si le gain de temps CPU est le moteur de ta demande, alors il suffit de parcourir le T1 via un For i allant du low au high de T1 (comme la syntaxe indiquée par Shail plus haut), ce qui ne fera donc que deux passages dans la boucle.
    Mettre alors le "Case of" dans le For, sauf que ce sera un Case of TMonTest(T1[i]). En supposant que cette syntaxe (T1[i]) soit acceptée sous Delphi.
    J'ai pas testé, c'est juste une propal pour aider.
    That was my 0.02£.

  8. #8
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    Est-ce que cocher ou non la case Optimisation dans les options de projet change quelque chose ??

  9. #9
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    J'ai toujours Optimisation de décocher sur mon Delphi (En général c'est une des premières choses que je fais quand j'installe un poste)

  10. #10
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    Comme ça, seulement 3 tours de boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
      for T2 in [mt1, mt3] do
      begin
        Inc(i);
        case T2 of
          mt1:
            Showmessage('mt1');
          mt2:
            Showmessage('mt2');
          mt3:
            Showmessage('mt3');
        end;
      end;

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Citation Envoyé par Rayek Voir le message
    J'ai toujours Optimisation de décocher sur mon Delphi
    Personnellement, je n'y touche jamais,
    selon Debug ou Release, on a pas les mêmes options par défaut à ce sujet il me semble ?!

    Papy214, tu ne compte que les tours visibles, Paul TOTH a évoqué des tours masqués que l'on ne peut voir qu'en assembleur !

  12. #12
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Personnellement, je n'y touche jamais,
    selon Debug ou Release, on a pas les mêmes options par défaut à ce sujet il me semble ?!
    Il m'est arrivé assez souvent des problèmes en débug à cause de l'optimisation (Ne passe pas dans la fonction malgré quelle soit utilisée dans d'autres, impossible d'aller dans des unités de Delphi avec un point d'arrêt, etc ...) d'où mon retrait systématique de cette option.

  13. #13
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    ShaiLeTroll : Je me base effectivement sur l'utilisation en pas à pas. L'assembler n'est pas vraiment ma tasse de thé. J'ai juste vu que le F8 me faisait passer 3 fois seulement dans la boucle avant de sortir.

  14. #14
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    ShaiLeTroll : Je me base effectivement sur l'utilisation en pas à pas. L'assembler n'est pas vraiment ma tasse de thé. J'ai juste vu que le F8 me faisait passer 3 fois seulement dans la boucle avant de sortir.
    utilise F7

    et si tu affiches le code assembleur tu retrouvera le "cmp al,$07" qui teste la valeur du registre AL qui sert à boucler de 0 à 7

Discussions similaires

  1. Question de curiosité sur du code
    Par defluc dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 08/09/2007, 16h12
  2. Curiosité sur temps d'executions
    Par wonderyan dans le forum C
    Réponses: 14
    Dernier message: 09/03/2007, 16h38
  3. Curiosité sur le prix d'un projet.
    Par snoopydo dans le forum Développement 2D, 3D et Jeux
    Réponses: 3
    Dernier message: 26/01/2007, 09h50
  4. [BATCH] Aide sur boucle for et test
    Par t_om84 dans le forum Windows
    Réponses: 3
    Dernier message: 07/06/2006, 10h12
  5. [VBA-E] Pb sur un For Each récalcitrant
    Par Squelet dans le forum Macros et VBA Excel
    Réponses: 27
    Dernier message: 20/03/2006, 13h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo