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

Delphi Discussion :

Optimisation de boucle 'while..do'


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 92
    Par défaut Optimisation de boucle 'while..do'
    Bonjour.
    D'après votre expérience, qu'elle est le meilleur moyen d'optimer la boucle suivante :

    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
     
     trouve:=true;
     while ( trouve ) do begin
      if ( query.Eof ) then
        trouve := false
      else begin
        vtmp := query.fieldbyname('code').asstring;
        if ( vtmp = 'TOTO' ) and ( bool1=false ) then begin
        	query.Next;
            continue;
        end;
        {* Traitement *}
       end;
       query.Next;
      end;
    Peut-on éviter d'avoir 2 fois query.Next??

    Merci d'avance.

  2. #2
    Membre éprouvé
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Par défaut
    Salut

    oui tu peux faire 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
    while not Query.Eof do
      try
      // instruction1
      ...
     
      // test
      if PasserALaSuiteSansExecuterInstruction2
        then Continue;
     
      // instruction2
      ...
     
      finally Query.Next; end
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  3. #3
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    J'ai pas testé mais ça ressemblerait à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
       while not query.Eof do
       begin
          if bool1 or
             (query.FieldByName('code').AsString <> 'TOTO') then
          begin
             {* Traitement *}
          end;
     
          query.Next;
       end;

  4. #4
    Blue_Strike
    Invité(e)
    Par défaut
    salut,
    le code du TicTac est le plus efficace meme au niveau de rapidité d'execution.

  5. #5
    Membre éprouvé
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Par défaut
    Merci BlueStrike, je pense aussi.
    Mais de toutes manière, ici ce n'est pas la prise de variables qui prend du temps mais bien l'accès au données.
    Les différences de temps entre les différents codes donnés seront imperceptibles à mon avis.

    Après c'est une question d'habitudes et de clarté

    Par contre,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    query.fieldbyname('code').asstring;
    Ce code prend du temps car la fonction fieldbyname est une recherche séquentielle sur le dataset query.

    si on veut réellement gagner en vitesse (mais pas forcément en clarté) il faudrait faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var
      FieldCode: TStringField;
    begin
      FieldCode := query.fieldbyname('code'); // une fois pour toute
     
      while ...
        begin
        ...
        utiliser 'FieldCode.AsString' // accès instantané au champs
        ...
        end;
    EDIT: je rejoins slimjoe aussi, RecordCount n'est pas à utiliser ici, + de temps et + de risque
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 92
    Par défaut
    Je connaissais pas cette technique... Intéressant.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 92
    Par défaut
    merci.

  8. #8
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 33
    Par défaut For
    1- avec ton query tu dois avoir un recordcount
    2- Tu a la fonction exit pour sortir de la fonction


    donc moi je ferais
    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
     
    procedure  blablab ()
    var 
    i : integer
    begin
     
    for i:= 0 to query.recordcount-1 do
    begin
     
     vtmp := query.fieldbyname('code').asstring;
        if ( vtmp <> 'TOTO' ) and ( bool1<>false ) then begin
        	---tu fais ton traitement------
        end;
     
     query.next;
     
    end;
    avec le recordcount tu connais le nombre d'enregistremen , tu connais le nombre = boucle for

    on peu peu etre optimiser encore mais ej crois que c'est un début

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 92
    Par défaut
    Merci pour votre aide je vais tester les 2.
    a+

  10. #10
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Citation Envoyé par sawbo1
    1- avec ton query tu dois avoir un recordcount
    2- Tu a la fonction exit pour sortir de la fonction


    donc moi je ferais
    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
     
    procedure  blablab ()
    var 
    i : integer
    begin
     
    for i:= 0 to query.recordcount-1 do
    begin
     
     vtmp := query.fieldbyname('code').asstring;
        if ( vtmp <> 'TOTO' ) and ( bool1<>false ) then begin
        	---tu fais ton traitement------
        end;
     
     query.next;
     
    end;
    avec le recordcount tu connais le nombre d'enregistremen , tu connais le nombre = boucle for

    on peu peu etre optimiser encore mais ej crois que c'est un début

    Salut!

    Petite opinion personelle : dépendemment du pilote, RecordCount est parfois un peu lent et la raison en est simple. Certains pilotes, sur des jeux d'enregistrements lourds, vont commencer par retourner les premiers enregistrements et continuer à charger les suivants en arrière plan (probablement dans un thread séparé). À ce moment précis, on ne connait pas RecordCount. Si on accède à cette propriété (ou si on appelle la méthode Last) on force le pilote à se rendre au dernier enregistrement avant de nous donner une réponse. Sur un jeu de plusieurs centaines de milliers d'enregistrement ça peut être long et si c'est seulement pour parcourir les enregistrements, je crois que c'est inutile.

    En fait, avec les années, j'ai découvert que les moments où j'avais vraiment besoin de RecordCount étaient vraiment rares. Effectivement, quand on y pense 2 secondes, on voit bien que de connaître le nombre d'enregistrements n'est pas une information que l'on a besoin régulièrement. Perso, je n'utilise le RecordCount que lorsque je dois faire fonctionner une barre de progression par exemple.

    C'était mon opinion, je ne veux pas l'imposer à personne d'autant plus que je n'ai pas la prétention de tout connaître sur le sujet . Mais comme l'objet de ce post était "comment optimiser ma requête" je crois que je me devais de vous en faire part.

    Bon dev à tous!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Optimisation Boucle While
    Par Fooshi dans le forum C
    Réponses: 15
    Dernier message: 28/06/2010, 11h55
  2. Optimisation de boucle while
    Par dyouknow dans le forum MATLAB
    Réponses: 2
    Dernier message: 16/05/2010, 19h15
  3. [PHP 5.0] Optimisation boucle while pour envoi d'e-mails
    Par renaud26 dans le forum Langage
    Réponses: 1
    Dernier message: 18/02/2010, 08h22
  4. optimiser une boucle while imbriquer dans une boucle for
    Par bakaratoun dans le forum MATLAB
    Réponses: 0
    Dernier message: 28/01/2010, 15h35
  5. optimisation d'une requête+deux curseurs+deux boucles while
    Par jawadi95 dans le forum Développement
    Réponses: 1
    Dernier message: 10/07/2008, 10h59

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