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 :

Améliorer le temps de traitement de chaînes


Sujet :

Delphi

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations forums :
    Inscription : Juin 2012
    Messages : 142
    Points : 80
    Points
    80
    Par défaut Améliorer le temps de traitement de chaînes
    Bonjour ,

    j'aimerais améliorer le temps de traitement de cette procédure qui consiste a indenter chaque ligne d'un mémo , je la trouve énormément longue à traiter toute les lignes du mémo.

    Ma méthode :

    Exemple d'une ligne : "G01 j0 x-10 F52"

    1: On retire les espaces de la ligne (LnTrim) : "G01j0x-10F52"
    2: On convertie la ligne en majuscule (UpperCase) : "G01J0X-10F52"
    3: On recherche les délimiteurs de la chaine (if pos then), pour chaque délimiteurs qui correspond a la condition, on luis insert un espace a la position du délimiteur : "G01 J0 X-10 F52"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {ABC := LnTrim(A B C)}
    function LnTrim(Ln: String): String;
    var
      ILn: Integer;
    begin
      for ILn := 1 to Length(Ln) do
       begin
         if not CharInSet(Ln[ILn], [#32]) then Result := Result + Ln[ILn];
       end;
    end;

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    procedure TForm1.BtIndenterClick(Sender: TObject);
    var
      ILn: Integer;
      Ln: String;
    begin
     
      with Memo do
       begin
        Gauge.MaxValue := Lines.Count;
     
        ReadOnly := True;
        Lines.BeginUpdate;
     
        for ILn := 0 to Lines.Count -1 do
         begin
    // On touche pas au commentaire (*//);
           if Pos('*//', Lines.Strings[ILn]) = 1 then Continue;
     
           Ln := EmptyStr;
    // On retire les espaces & convertie la ligne en majuscule
           Ln := LnTrim(UpperCase(Lines.Strings[ILn]));
     
    // Si la ligne est vide , on la remplace par un commentaire (*//)
           if Ln = EmptyStr then
            begin
              Ln := '*// !!! Ln n/a !!!';
              Lines.Strings[ILn] := Ln;
              Continue;
            end;
     
           if Pos('J', Ln) <> 0 then
            begin
              Insert(#32, Ln, Pos('J', Ln));
            end;
     
           if Pos('F', Ln) <> 0 then
            begin
              Insert(#32, Ln, Pos('F', Ln));
            end;
     
           if Pos('X', Ln) <> 0 then
            begin
              Insert(#32, Ln, Pos('X', Ln));
            end;
     
           Lines.Strings[ILn] := Ln;
     
           Gauge.Progress := ILn;
           Application.ProcessMessages;
         end;
     
        Gauge.Progress := 0;
        Gauge.Refresh;
     
        Lines.EndUpdate;
        ReadOnly := False;
     
      end;
    Auriez vous une méthode plus efficace qui pourrai amélioré le temps de traitement ?

    Merci.
    Il n'existe guère de problèmes sans solution, et parfois l'absence de solution décourage le problème

  2. #2
    Membre expérimenté
    Avatar de retwas
    Homme Profil pro
    Développeur Java/Delphi
    Inscrit en
    Mars 2010
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java/Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 698
    Points : 1 608
    Points
    1 608
    Billets dans le blog
    4
    Par défaut
    Un StringReplace des espaces par '' est peut etre plus rapide que ta fonction Lntrim, en tout cas c'est plus simple ^^

    Tu peux encapsuler le beginupdate et endupdate dans un try ... finally, tu n'as pas besoin du Application.ProcessMessages nan ?

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations forums :
    Inscription : Juin 2012
    Messages : 142
    Points : 80
    Points
    80
    Par défaut
    J'ai fait quelque teste en supprimant " Application.ProcessMessages & Gauge.Progress := ILn "

    le temps de traitement de la procédure se joue à quelque millisecondes sans " Application.ProcessMessages & Gauge.Progress := ILn "

    Finalement, c'est pas sa qui réduit énormément temps de traitement.

    J'avais déjà fait quelque teste sur la fonction "Lntrim" pour une longue de chaine de 2000 caractères son temps de traitement été de 0 milliseconde.
    Il n'existe guère de problèmes sans solution, et parfois l'absence de solution décourage le problème

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 030
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 030
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    c'est quoi les "délimiteurs' GJXF ? toujours dans le même ordre ?
    quelle est la version de Delphi ?
    avez vous pensé aux expressions régulières ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations forums :
    Inscription : Juin 2012
    Messages : 142
    Points : 80
    Points
    80
    Par défaut
    Oui il son toujours dans le mème ordre logiquement. mais je préféré anticipé le désordre

    G01 : Une fonction
    J : N° Servomoteur
    X : Coordonné de déplacement
    F: Vitesse programmé

    j'ai pris comme exemple G01 mais j'ai d'autre fonction qui comporte d'autre délimiteur exemple : SVM J0 I200/2500 DEG180 F500 OP86

    Delphi XE8
    Il n'existe guère de problèmes sans solution, et parfois l'absence de solution décourage le problème

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    392
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 392
    Points : 635
    Points
    635
    Par défaut
    tu gagnerais beaucoup à faire tout tes traitement directement dans une seule boucle lors du parcourt pour éliminer les espaces, puisque tu testes tout les caractères autant que cela serve

    dans ton code en plus tu fais plusieurs fois le même calcul pour les Pos(...)

  7. #7
    Membre expérimenté
    Avatar de retwas
    Homme Profil pro
    Développeur Java/Delphi
    Inscrit en
    Mars 2010
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java/Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 698
    Points : 1 608
    Points
    1 608
    Billets dans le blog
    4
    Par défaut
    C'est quasiment instantané avec une StringList locale, plutôt que de travailler directement sur le Memo.

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    procedure TForm2.Button2Click(Sender: TObject);
    var
       iLn  : integer;
       ln   : string;
       List : TStringList;
    begin
       List := TStringList.Create;
     
       try
          Memo.Lines.BeginUpdate;
          Memo.ReadOnly := True;
     
          List.Assign(Memo.Lines);
          Gauge.Max     := List.Count;
     
          for iLn := 0 to List.Count - 1 do
          begin
             if Pos('*//', List[iLn]) = 1 then
                Continue
             else
             begin
                ln := UpperCase(StringReplace(List[iLn], ' ', '', [rfReplaceAll, rfIgnoreCase]));
     
                if ln = '' then
                begin
                   Ln := '*// !!! Ln n/a !!!';
                   List[iLn] := ln;
                   Continue;
                end
                else
                begin
                   if Pos('J', Ln) <> 0 then
                   Insert(#32, Ln, Pos('J', Ln));
     
                   if Pos('F', Ln) <> 0 then
                   Insert(#32, Ln, Pos('F', Ln));
     
                   if Pos('X', Ln) <> 0 then
                   Insert(#32, Ln, Pos('X', Ln));
     
                   List[ILn] := Ln;
                end;
             end;
     
             Gauge.Position := iLn;
             Application.ProcessMessages;
          end;
     
          Memo.Lines.Assign(List);
       finally
          FreeAndNil(List);
          Memo.ReadOnly := False;
          Memo.Lines.EndUpdate;
       end;
    end;

  8. #8
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations forums :
    Inscription : Juin 2012
    Messages : 142
    Points : 80
    Points
    80
    Par défaut
    Oui effectivement , j'ai fait un teste avec plus de 5000 ligne sa a durée à peine 2 secondes
    Il n'existe guère de problèmes sans solution, et parfois l'absence de solution décourage le problème

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

Discussions similaires

  1. [11gR2] Améliorer un temps de traitement
    Par sam01 dans le forum PL/SQL
    Réponses: 3
    Dernier message: 20/05/2016, 12h00
  2. [python{2.7,3.4} Amélioration des temps de traitement
    Par avi3000 dans le forum Général Python
    Réponses: 18
    Dernier message: 15/08/2014, 16h12
  3. [MySql] temps de traitement interminable
    Par LE NEINDRE dans le forum Requêtes
    Réponses: 8
    Dernier message: 08/07/2005, 15h14
  4. [Perf]Utilisation des Logger et temps de traitement ?
    Par elitost dans le forum Logging
    Réponses: 6
    Dernier message: 12/04/2005, 23h13
  5. optimisation de temps de traitement xml/xslt
    Par Erwy dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 06/05/2004, 16h08

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