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 :

TStringList et fréquence des mots.


Sujet :

Delphi

  1. #41
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Grow c'est une méthode Privée, faut lire le source ...
    Sinon Affiché les 1500 itérations ne sert à rien la dernière suffit, ... c'est ce que je fait, car j'ai dans la 30aine de variante, sans compter les appels d'Explode avec tous les cas que j'ai pu trouvé pour mes tests, ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  2. #42
    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
    A ShaiLeTroll :
    Sinon Affiché les 1500 itérations ne sert à rien la dernière suffit
    ... oui mais ça suffit uniquement pour faire un test de vitesse avec 1000 fois la même ligne de test, mais si on veut accumuler dans le tableau A les Splits sur 1000 lignes toutes différentes l'une de l'autre on ne retrouverait que le résultat du dernier appel à ExplodeLazyPChar ... raison pour laquelle je pensais qu'il y aurait une astuce pour accumuler l'ensemble dans une StringList.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  3. #43
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    L'accumulation fausse le test, car tu ne teste plus la fonction, mais la fonction plus de l'accumulation, ...

    mais pour l'accumulation sans mesure de temps, tu peux mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i:=Low(A) to High(A) do RichEdit1.lines.Add(A[i]);
    après chaque appel ...

    Sinon, je ne teste qu'avec qu'une ListBox, c'est le composant dont les TStrings sont les plus proche de la TStringList et ne font aucune modification de contenu comme le TMemo ou le TRichEdit ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #44
    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
    A ShaiLeTroll :
    L'accumulation fausse le test, car tu ne teste plus la fonction, mais la fonction plus de l'accumulation
    ... c'est effectivement une façon de voir les choses, par contre si l'objectif global est d'accumuler je préfère faire porter les test de vitesse sur l'ensemble splittage+accumulation, et c'est d'ailleurs ce que fait ma version d'ExplodeLazy où, n'ayant pas trouvé dans un 1er temps l'unité "Types" à ajouter dans les USES pour le TStringDynArray, j'ai simplement remplacé le TStringDynArray par une StringList alimentée par Add.

    A propos de ExplodeLazyPChar :
    mais pour l'accumulation sans mesure de temps, tu peux mettre for i:=Low(A) to High(A) do RichEdit1.lines.Add(A[i]);après chaque appel ...
    ... effectivement en accumulant après chaque appel c'est une parade qui permet d'accumuler dans n'importe quel conteneur de lignes.

    Nouvelle fonction de splittage : Voiçi une variante améliorée d'ExplodeGG où tous les mots splittés sont séparés par des #13#10 et accumulés à la volée dans un MemoryStream :
    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
     
    function  ExplodeGGMS(const S : string; var MS : TMemoryStream; Sep : Char) : Integer; // V4
    var       ic,ib : integer; buff : array [0..4096] of char;
    begin     Result:=0; ib:=-1;
              for ic:=1 to length(S) do
              begin if S[ic] <> Sep
                    then begin inc(ib); buff[ib]:=S[ic]; end
                    else begin Inc(Result);
                               inc(ib); buff[ib]:=#13;
                               inc(ib); buff[ib]:=#10; end;
              end;
              if S[length(S)] <> Sep then
              begin inc(ib); buff[ib]:=#13; inc(ib); buff[ib]:=#10; end;
              MS.Write(buff,ib+1);
    end;
     
    procedure TForm1.bExplodeGGMSClick(Sender: TObject);
    var       MS : tMemoryStream; i : integer; Chrono : oChrono;
    begin     ListBox1.clear;
              Chrono.Top;
              MS := tMemoryStream.create;
              MS.Position:=0;
              for i:=1 to 1000 do ExplodeGGMS(ligTests,MS,';');
              labChrono.caption:='Mis : '+FloatToStrf(Chrono.Mis,ffFixed,10,2);
              //< mis 1,12 ms avec Pentium III 1,13 Ghz
              labChrono.upDate;
              MS.Position:=0;
              ListBox1.Items.LoadFromStream(MS);
              labCount.caption:=IntToStr(ListBox1.Items.Count);
              MS.Free;
    end;
    ... Temps d'Execution d'ExplodeGGMS sur [0;;1;2!2;333;44!44;55555;666!666;7777777;8888!8888;999999999;00000!00000;"AAA";"BBB";"CCC"] découpé sur ; répété 1000 fois avec splittage ET accumulation dans le MémoryStream : 1,12 ms avec Pentium III à 1,13 Ghz.
    ... pas mécontent du résultat, si ça peut rendre service à qqu'un.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  5. #45
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Juste comme çà, la fonction n'explode rien, mais fait un simple ReplaceString et copie le résultat dans un TStream, donc le réel explode est fait par le LoadFromStream ... pour moi, cette fonction ne propose pas le même résultat c'est à dire un tableau/liste contenant les chaines séparés que l'on peut parcourir facilement.

    Comparer les temps sur une fonction qui ne fait pas le même résultat n'a pas de sens ...

    Il est vrai l'acculumation du résultat d'un explode (pas la version Lazy) peut servir pour l'affichage d'un csv dans une grille par exemple ... sinon je vois rien d'autres ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #46
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    624
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 624
    Points : 199
    Points
    199
    Par défaut
    Salut Gilbert,

    Je rejoins un peu ce que dit ShailLeTroll car en fait pour moi c'est vraiment le fait d'avoir le résultat dans une List qui m'interesse.

    Amicalement,
    Bruno

  7. #47
    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
    A ShaiLeTroll :
    ... peu importe, l'essentiel est que ça marche bien, et comme le Stream contient bien la totalité des chaines séparées on peut les charger à souhait dans une StringList si on veut pouvoir les parcourir facilement et qu'on n'a pas besoin de les visualiser, ou bien si on veut les accumuler dans un contrôle de visualisation au prix du ralentissement correspondant on peut les envoyer dans une ListBox, un Memo ou un RichEdit. Pour ma part je considère qu'une chaîne est splittée dès lors que les séparateurs y sont remplacés par des #13#10 qui découpent cette chaîne en des mini-chaînes, que ces mini-chaînes soient à l'intérieur d'un Stream ou d'autre chose. Bon, j'ai utilisé un MemoryStream, j'aurais aussi bien pu faire avec un TStringStream, mais comme le MemoryStream fonctionne tout aussi bien j'ai pris celui-ci ... si ça me prend j'essayerai avec un TStringStream un prochain jour.


    P.S : En fait LoadFromStream n'explode rien du tout il ne fait que transmettre au destinataire ce qui a été explodé-splitté au préalable par la fonction et si on donne à LoadFromStream un stream non splitté ce n'est certainement pas LoadFromStream qui fera les splits à la place de la fonction.
    Et pour ce qui est des temps d'exécution il est exact qu'ils nont de sens que si on compare des fonctions qui renvoient les mêmes résultats ce qui nécessiterait de modifier ExplodeLazy par exemple de sorte qu'elle renvoie la totalité des splits qu'elle produit dans un boucle d'appel et non seulement ceux du dernier appel car l'objectif n'est pas de splitter pour splitter mais de récupérer la totalité des splits ce qui nécessite bien entendu que ce soit ExplodeLazy qui engrange tous les splits dans le même tableau ou alors c'est dans la boucle d'appel qu'il faut, après chaque appel, transférer les résultats partiels dans un tableau annexe ce qui prend bien entendu un temps non pris en compte dans le score affiché et dans les comparaisons.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  8. #48
    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
    Salut Bruno,

    Comme ton message s'est intercalé devant le mien pendant que je le rédigais et qu'en même temps j'ai fait autre chose, je pense que ma réponse à ta remarque se trouve dans ma réponse à ShaiLeTroll : Si tu veux le résultat dans une List :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                ...
                for i:=1 to 1000 do ExplodeGGMS(ligTests,MS,';');
                MS.Position:=0;
                SL := tStringList.create;
                SL.LoadFromStream(MS);
    ... et le tour est joué.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  9. #49
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    624
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 624
    Points : 199
    Points
    199
    Par défaut
    j'etais justement en train de composer un message qui faisait cela

  10. #50
    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
    A Bruno13,

    Salut Bruno,

    Vérification faite, le remplacement du TMemoryStream par un TStringStream aboutit à peu près à des temps d'exécution identiques.
    La principale différence avec TStringStream est de pouvoir récupérer la totalité des splits soit par ReadString soit par LoadFromStream :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                SL := tStringList.create
                SS.Position:=0; 
                SL.Text:=SS.ReadString(SS.size);
                // ou bien :
                SS.Position:=0;
                SL.LoadFromStream(SS);
    ... mais pour les reste c'est kif-kif.

    Autre vérification faite avec une variante de la fonction ExplodeGGMS où au lieu de splitter sur un seul séparateur le test de splittage portait sur la vérification de présence de 10 séparateurs le temps d'exécution a seulement été multiplié par deux.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  11. #51
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    624
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 624
    Points : 199
    Points
    199
    Par défaut
    Salut Gilbert,

    Je vais tester cela d'ici peu. Je te tiens informé. Là je bloque sur la qualité du resultat que j'obtiens avec ma détection de Concept. hum pas évident du tout

  12. #52
    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
    Salut Bruno,
    Là je bloque sur la qualité du resultat que j'obtiens avec ma détection de Concept. hum pas évident du tout
    ... je suppose que tu fais allusion au BrainStorming de l'autre dicussion : effectivement c'est pas évident et en plusieurs langues ça l'est encore moins, mais wait and see il y aura peut-être des idées. J'ai cherché sur Google avec bi-gramme tri-gramme et n-gramme on y trouve une floppée de théories mais je n'ai pas trouvé de trucs bien concrets qui aboutiraient à un résultat indiscutable.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #53
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    624
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 624
    Points : 199
    Points
    199
    Par défaut
    Pour les n-grammes, c'est pour la détection de la langue ? Pour ça ce que tu m'as fourni est largement suffisant, je reste sur 5 langues et j'ai un résultat plus que satisfaisant donc je passe à la suite... au fameux BrainStorming

  14. #54
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par Gilbert Geyer
    A ShaiLeTroll :
    ... Pour ma part je considère qu'une chaîne est splittée dès lors que les séparateurs y sont remplacés par des #13#10 qui découpent cette chaîne en des mini-chaînes, que ces mini-chaînes soient à l'intérieur d'un Stream ou d'autre chose.

    P.S : En fait LoadFromStream n'explode rien du tout il ne fait que transmettre au destinataire ce qui a été explodé-splitté au préalable par la fonction et si on donne à LoadFromStream un stream non splitté ce n'est certainement pas LoadFromStream qui fera les splits à la place de la fonction.
    Il n'y a pas de "Pour ma part", splitté c'est découpé en morceaux un ensemble, et remplacer un caracètère par une série de caractère ne sera jamais un split mais un remplacement, et je confirme le VRAI explode est fait par le LoadFromStream qui utilise comme caractère de séparation le #10 ou le #13 et le #0

    La Fonction Explode n'a qu'un seul but, on lui donne une entrée chaine et cela ressort un tableau de chaine, ensuite, tu peux utiliser mon wrapper, car j'avais déjà pensé au besoin d'accumulation ou au fait que mes collègues préfèrent manipuler des TStringList que des Array ...

    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
    {* -----------------------------------------------------------------------------
    la fonction ExplodeLazyToStrings encapsule ExplodeLazy pour renvoyer une liste.
    @param S Chaine à découper
    @param A Tableau de Chaine qui recevra la découpe
    @param Separator Caractère qui délimitent une chaine pour la découpe
    @return Nombre de Séparateur Trouvé (peut-être différent du nombre de chaine dans A !)
    ------------------------------------------------------------------------------ }
    function ExplodeLazyToStrings(const S: string; L: TStrings; Separator: Char; DoClear: Boolean = True): Integer;
    var
      A: Types.TStringDynArray;
      iL: Integer;
    begin
      if Assigned(L) then
      begin
        Result := Explode(S, A, Separator);
        if DoClear then
        begin
          L.Clear();
          L.Capacity := Result;
        end else
          L.Capacity := L.Capacity + Result;
     
        for iL := Low(A) to High(A) do
          L.Add(A[iL]);
      end else
        Result := -1;
    end;
    voir le code de Classes.pas

    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
    procedure TStrings.LoadFromStream(Stream: TStream);
    var
      Size: Integer;
      S: string;
    begin
      BeginUpdate;
      try
        Size := Stream.Size - Stream.Position;
        SetString(S, nil, Size);
        Stream.Read(Pointer(S)^, Size);
        SetTextStr(S);
      finally
        EndUpdate;
      end;
    end;
    tu notteras SetTextStr ressemble très nettement à un explode en PChar ... SetString étant l'équivalent du SetLength+Move ...
    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
    procedure TStrings.SetTextStr(const Value: string);
    var
      P, Start: PChar;
      S: string;
    begin
      BeginUpdate;
      try
        Clear;
        P := Pointer(Value);
        if P <> nil then
          while P^ <> #0 do
          begin
            Start := P;
            while not (P^ in [#0, #10, #13]) do Inc(P);
            SetString(S, Start, P - Start);
            Add(S);
            if P^ = #13 then Inc(P);
            if P^ = #10 then Inc(P);
          end;
      finally
        EndUpdate;
      end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  15. #55
    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 ShaiLeTroll,
    LoadFromStream qui utilise comme caractère de séparation le #10 ou le #13 et le #0
    ... wouais ? sauf que lorsque je sauve les résultats du splittage sur le disque et que j'ouvre le fichier avec un Editeur Hexa je n'y trouve que des 0D0A c'est à dire #13#10 comme séparateurs !!! et nulle part aucun #0 ! Pas convaincant l'histoire du #0 ajouté comme séparateur. Ce n'est pas parceque le SetTextStr teste la présence éventuelle d'un #0 qu'il le rajoute comme séparateur. Et LoadFromStream laisse passer comme le facteur toute chaine spllittée ou non splittée.
    Mais dans tout ça, l'essentiel c'est que ça marche, non ?

    Pour ce qui est de la function ExplodeLazyToStrings qui répond au besoin d'accumulation je testerai demain mais je m'attends à obtenir le même temps d'exécution qu'avec ma variante la function ExplodeLazySL(const S: string; var SL: TStringList; Separator: Char): Integer où la TStringList SL remplace directement le tableau 'A' qui n'accumulait que les splits du dernier appel et celle-ci met 13 à 18,42 ms avec la chaine de tests répétée 1000 fois (Pentium III 1,13 Ghz)
    J'ai deux autres variantes d'ExplodeLazy où j'ai conservé le tableau 'A' mais modifié les setLength et les indices pour tenir compte de Lg0:=High(A)+1; longueur initiale du tableau au moment de l'appel pour y accumuler tous les splits résultant de la série d'appels par boucle, mais les deux versions (avec ou sans PChar) conduisent à des temps d'exécution de l'ordre de 160 ms ... ce qui une fois de plus confirme l'intérêt et la vélocité des StringList.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  16. #56
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    oui, c'était un "et" dans le sens qu'il gère le #0, suffisait de lire le code "(P^ in [#0, #10, #13]) ", tu chippote !

    Sinon, pour le Tableau, bien sur, l'allocation sans prévision (ce que fait la TStringList avec sa méthode privée Grow) est très lente, et toute la lenteur de l'accumulation est l'agrandissement de la mémoire au fur et à mesure, le parcours des chaines est à coté insignifiant ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  17. #57
    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
    Sinon, pour le Tableau, bien sur, l'allocation sans prévision (ce que fait la TStringList avec sa méthode privée Grow) est très lente, et toute la lenteur de l'accumulation est l'agrandissement de la mémoire au fur et à mesure, le parcours des chaines est à coté insignifiant
    ... au final la StringList est plus dynamique que les tableaux-dits-dynamiques,
    ... et les Streams sont encore plus dynamiques que les StringList.

    tu chippote !
    ... peut on vraiment faire de la micro-informatique sans chipoter, alors qu'au moindre oubli d'un point ou d'une virgule la machine nous envoie ballader?
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  18. #58
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    La TStringList est un Tableau Dynamique !
    Mais elle apporte une gestion intelligente de la mémoire (voir Capacity) puisqu'il y a une allocation prévisionnelle par lot ... et c'est justement pour ce que dans Explode, je compte le nombre de séparateur pour allouer le tableau en une seule fois, le gain est énorme ...

    Pour le Stream,
    si c'est à base de THandleStream c'est du Fichier, pipe, socket ... limitation habituelle, temps d'execution dépendant bcp des conditions systèmes, des DD, du réseau, ...
    si c'est à base de TMemoryStream c'est du pointeur, donc gestion mémoire standard, et finalement, tout dépend de la taille pré-alloué, ... comme dans ton exemple tu écrit dans le stream une seule fois, cela gagne du temps car une seule allocation
    si c'est à base de TStringStream, c'est une string qui est derrière donc aucun intérêt pour Exploder ...

    Voilà, c'est très simple ...

    tu devrais essayer les Pointers, tu comprendrais mieux ces Objets et comment fonctionne la mémoire ... consulte donc l'unité Classes.pas, tu devrais y trouver l'implementation de la StringList et autres ... j'y ai appris bcp de choses ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  19. #59
    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 ShaiLeTroll

    1)
    La TStringList est un Tableau Dynamique !
    ... oui oui, tu l'avais déjà souligné dans une autre discussion. En fait quand j'ai dit "au final la StringList est plus dynamique que les tableaux-dits-dynamiques" c'était surtout un jeu de mots en faveur des StringList.
    ... dommage qu'il n'ait pas été prévu d'allocation prévisionnelle par lot pour les tableaux-dits-dynamiques cela les aurait mis sur un pied d'égalité avec TStringList.

    2)
    si c'est à base de TStringStream, c'est une string qui est derrière donc aucun intérêt pour Exploder
    ... pourtant ma variante avec TStringStream est tout aussi rapide que celle avec TMemoryStream et de plus elle permet de récupérer le résultat de trois manières différentes ce qui est également intéressant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
             SL := tStringList.create;
             SS.Position:=0;
                  1) SL.Text:=SS.ReadString(SS.size); // et en jouant avec SS.Position et ReadString(count) on peut même faire une extraction sélective dans le cas de splits de même longueur
                  2) SL.Text:=SS.DataString;
               ou 3) SL.LoadFromStream(SS);
    3) Tests avec la function ExplodeLazyToStrings(const S: string; L: TStrings; Separator: Char; DoClear: Boolean = True): Integer : je n'ai pas pu faire de tests car elle encapsule Explode(S, A, Separator) et celle-ci utilise des IfThen qui n'existent pas sous Delphi-5.
    Par contre je trouve dommage d'encapsuler celle-ci derrière le paramètre Separator: Char qui est restrictif alors qu'Explode permet des splits-multiséparateurs.
    Je préfère plutôt une version de ExplodeLazy qui n'encapsule pas Explode() mais dans laquelle le out A: Types.TStringDynArray est directement remplacé par var SL : TStringList et qui rend superflue l'existence d'ExplodeLazyToStrings puisque l'ExplodeLazy mono-séparateur ainsi modifiée réalise l'accumulation tout aussi bien directement et en se passant des SetLength-ralentisseurs.
    Et pour ce qui est d'encapsuler Explode() pour l'accumulation je verrais donc mieux l'existence d'une function ExplodeToStrings(const S: string; L: TStrings; Separator: string; DoClear: Boolean = True): Integer
    Cela formerait un ensemble plus cohérent.

    4)
    consulte donc l'unité Classes.pas, tu devrais y trouver l'implementation de la StringList et autres ... j'y ai appris bcp de choses
    ... ok je la consulterai à l'occasion puisque tu dis y avoir appris bcp de choses
    ... j'hésite toujours un peu à tripatouiller dans les fichiers des dossiers de Delphi pour éviter d'y mettre le désordre.
    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

Discussions similaires

  1. calcul de fréquence des mots
    Par doceln dans le forum MATLAB
    Réponses: 8
    Dernier message: 01/10/2012, 21h27
  2. Fréquences des mots : la méthode TF-IDF
    Par pyknite dans le forum Intelligence artificielle
    Réponses: 2
    Dernier message: 25/06/2009, 09h01
  3. Mettre la première lettre des mots en majuscule
    Par seb.49 dans le forum Langage
    Réponses: 8
    Dernier message: 23/05/2003, 14h26
  4. Au sujet des mots de passe
    Par FranT dans le forum Langage
    Réponses: 6
    Dernier message: 17/09/2002, 22h16

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