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

Composants VCL Delphi Discussion :

Lenteur de RichEdit.Lines.Assign(StringList)


Sujet :

Composants VCL Delphi

  1. #1
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut Lenteur de RichEdit.Lines.Assign(StringList)
    Bonjour,

    Quelqu'un pourrait-il m'expliquer pourquoi RichEdit.Lines.Assign(SLSource) est 27 fois plus lent que ma procedure AssignMaison(const SLSource: TStringList; var RichEd: TRichEdit) lorsque à partir d'un fichier de 1 Mo j'en extrais la StringList
    que j'assigne 10 fois de suite à un RichEdit avec le code ci-après :

    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
    59
    60
     
    var SLSource: TStringList;
     
    procedure TForm1.bChargerZolaClick(Sender: TObject);
    var FileName: string;
    begin
      RichEdit1.Clear;
      FileName := ExtractFilePath(Application.ExeName) + 'Zola1Mo.txt';
      TopChrono;
      with RichEdit1 do begin
        Lines.BeginUpdate;
        Clear;
        Lines.LoadFromFile(FileName);
        Lines.EndUpdate;
      end;
      Edit1.Text := fGoMoKo(TailleFichier(FileName));
     
      SLSource := TStringList.Create;
      SLSource.Assign(RichEdit1.Lines);
      RichEdit2.Clear;
    end;
     
    procedure TForm1.bDixFoisAssignStandardClick(Sender: TObject);
    var i: integer;
    begin
      TopChrono; Sablier;
      for i := 1 to 10 do begin
        RichEdit1.Lines.BeginUpdate;
        RichEdit1.Clear;
        RichEdit1.Lines.Assign(SLSource);
        RichEdit1.Lines.EndUpdate;
      end;
      RichEdit2.Lines.Add('RichEdit1.Assign Standard : mis ' + fChrono);
      Sablier;
    end;
     
    procedure AssignMaison(const SLSource: TStringList; var RichEd: TRichEdit);
    var aStream: TMemoryStream;
    begin
      RichEd.Lines.Capacity := SLSource.Count;
      aStream := TMemoryStream.Create;
      SLSource.SaveToStream(aStream);
      aStream.Position := 0;
      RichEd.Lines.LoadFromStream(aStream);
      aStream.Free;
    end;
     
    procedure TForm1.bDixFoisAssignMaisonClick(Sender: TObject);
    var i: integer;
    begin
      TopChrono; Sablier;
      for i := 1 to 10 do begin
        RichEdit1.Lines.BeginUpdate;
        RichEdit1.Clear;
        AssignMaison(SLSource, RichEdit1);
        RichEdit1.Lines.EndUpdate;
      end;
      RichEdit2.Lines.Add('AssignMaison(SLSource,RichEdit1) : mis ' + fChrono);
      Sablier;
    end;
    A+.
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Quelqu'un pourrait-il m'expliquer pourquoi RichEdit.Lines.Assign(SLSource) est 27 fois plus lent que ma procedure AssignMaison(const SLSource: TStringList; var RichEd: TRichEdit) lorsque à partir d'un fichier de 1 Mo j'en extrais la StringList que j'assigne 10 fois de suite à un RichEdit avec le code ci-après :...
    Tout est dans le code de la RTL.
    Assign traite les éléments de la liste source 1 par 1 en considérant qu'ils peuvent être associés à un objet.
    LoadFromStream ne s'occupe que de construire les éléments string de la liste en décomposant la string du stream.
    Philippe.

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Ph. B. : Assign traite les éléments de la liste source 1 par 1 en considérant qu'ils peuvent être associés à un objet.
    LoadFromStream ne s'occupe que de construire les éléments string de la liste en décomposant la string du stream.
    Ah bon ? J'étais persuadé qu'en chargeant la StringList dans un MemeoryStream ce Stream contiendrait toutes les propriétés et caractéristiques de la StringList-source y compris l'objet éventuellement associé via AddObject et que le LoadFromStream transférerait tout ça au RichEdit : bigre.
    Par contre ça n'explique pas complètement pourquoi Assign est 27 fois plus lent qu'un transfert via un Stream car comme l'objet associé à chaque String de la TStringList n'est qu'un simple pointeur cela devrait à mon avis être plus rapide même en traitant les éléments de la liste 1 par 1 : mystère et boule de gomme ! (27 fois c'est énorme)

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #4
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par Gilbert Geyer Voir le message
    Ah bon ? J'étais persuadé qu'en chargeant la StringList dans un MemeoryStream ce Stream contiendrait toutes les propriétés et caractéristiques de la StringList-source y compris l'objet éventuellement associé via AddObject et que le LoadFromStream transférerait tout ça au RichEdit : bigre.
    Dans ce cas, il faudrait sérialiser puis désérialiser les objets pour les intégrer au flux (stream) mais cela pose quelques problèmes de gestion des références(recréation, libération, liens avec d'autres objets non associés à la stringlist)...
    Citation Envoyé par Gilbert Geyer Voir le message
    Par contre ça n'explique pas complètement pourquoi Assign est 27 fois plus lent qu'un transfert via un Stream car comme l'objet associé à chaque String de la TStringList n'est qu'un simple pointeur cela devrait à mon avis être plus rapide même en traitant les éléments de la liste 1 par 1 : mystère et boule de gomme ! (27 fois c'est énorme)
    D'un côté, on parcourt une chaine de caractères source et on n'affecte élément par élément que les chaines (on ne traite pas les objets associés) à la liste destination.
    De l'autre, on lit élément par élément (chaine de caractères et objet lié) la liste source et on l'affecte élément par élément (chaine et objet) à la liste destination. Les appels de procédure (donc empilage, dépilage) sont nettement plus nombreux dans ce cas.
    Philippe.

  5. #5
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour et bonne année,

    Ph. B. Dans ce cas, il faudrait sérialiser puis désérialiser les objets pour les intégrer au flux (stream) mais cela pose quelques problèmes de gestion des références(recréation, libération, liens avec d'autres objets non associés à la stringlist)...
    Bin comme je n'ai pas besoin de transmettre des objets au RichEdit je me contente d'aller environ 27 fois plus rapidement en lui transmettant les string's de la StringList via un Stream.
    Comme en plus un TRichEdit ne gère pas l'affichage d'un BitMap parmi le texte je ne vois même pas l'intérêt de lui transmettre un objet via Assign

    Cordialement, et à+.

    Edit :
    D'un côté, on parcourt une chaine de caractères source et on n'affecte élément par élément que les chaines (on ne traite pas les objets associés) à la liste destination.
    De l'autre, on lit élément par élément (chaine de caractères et objet lié) la liste source et on l'affecte élément par élément (chaine et objet) à la liste destination. Les appels de procédure (donc empilage, dépilage) sont nettement plus nombreux dans ce cas.
    Bin justement que non car dans les tests comparatifs de speed, ma StringList ne contient que la littérature de Zola qui ne comporte aucun objet donc il n'y a aucun objet à gérer mais Assign semble perdre du temps à gérer des trucs inexistants.

    Vérification faite avec AddStrings on hérite de la même lenteur qu'avec Assign lorsque on leur transmet une StringList qui ne contient aucun objet. Très certainement parce qu'elles sont incapables de distinguer une StringList chargée d'objet(s) d'une autre qui n'en contient aucun : c'est vraiment dommage car on y gagnerait beaucoup en vitesse.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  6. #6
    Membre actif

    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2009
    Messages : 128
    Points : 203
    Points
    203
    Par défaut
    Salut Gilbert

    Moi, je crois (et croire apporte certainement son lot d'incertitude...) que ce sont les mouvements de recopies de kyrielles d'octets en RAM qui sont pénalisants. Je me demande d'ailleurs pourquoi dans ta méthode "maison" tu passes par une recopie du fichier dans ton stream alors qu'il pourrait très bien être déjà chargé directement par Stream.LoadFromFile auparavant ?

    Bof...

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour René,

    Rekin85: Moi, je crois (et croire apporte certainement son lot d'incertitude...) que ce sont les mouvements de recopies de kyrielles d'octets en RAM qui sont pénalisants.
    A mon avis si Assign utilise des mouvements de recopies cela explique en partie sa lenteur, par contre la kyrielle d'octets est la même que l'on passe par Assign ou par un Stream.

    Je me demande d'ailleurs pourquoi dans ta méthode "maison" tu passes par une recopie du fichier dans ton stream alors qu'il pourrait très bien être déjà chargé directement par Stream.LoadFromFile auparavant ?
    C'est tout bêtement parce que dans l'application dans laquelle j'ai découvert la lenteur de RichEdit.Lines.Assign avant de transmettre ma StringList au RichEdit cette StringList subit des transformations, mais ta remarque est judicieuse car en chargeant Zola directement dans le Stream avec Stream.LoadFromFile on évite un transfert d'octets d'où un gain de speed supplémentaire.

    Cordialement et à +.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

Discussions similaires

  1. Lenteur du read line
    Par qdqdfqfdqdxcwcrzsdfw dans le forum Langage
    Réponses: 22
    Dernier message: 17/01/2007, 11h29
  2. RichEdit->Lines comment indiquer l'indexe de ligne
    Par fastzombi dans le forum C++Builder
    Réponses: 5
    Dernier message: 05/12/2005, 10h19

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