Einzelnen Beitrag anzeigen

Benutzerbild von stoxx
stoxx

Registriert seit: 13. Aug 2003
1.111 Beiträge
 
#25

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code

  Alt 23. Feb 2008, 07:06
30%- 75% Prozent Performancegewinn gewinnst Du bei einem Seperator der Länge 1, wenn Du die lokale Funktion in der Explode Procedure weglässt.
(ein Zeichen als Seperator braucht man ja häufig für CSV Files)
Schon wenn die _AddString Procedure nur drin steht, und gar nicht aufgerufen wird, bricht die Performance durch den Aufruf-Stack massiv ein.
TStrings ist auch ein sehr schwieriges Nadelöhr. Vielleicht besser doch ein Dynarray als Ergebnistyp verwenden, neuerdings kann man ja auch Records Definieren, die einen String beinhalten können, obwohl nicht als Shortstring deklariert.
SetString könnte man noch durch die beste ASM Fastmove Funktion ersetzen. Dann wirds sogar noch schneller...
Wenn man dann noch mit CSV Dateien arbeitet, und weiß, dass eine Spalte wahrscheinlich nie länger als 255 Zeichen wird, dann ist shortstring noch etwas
schneller.
Dann schafft man es auch, eine 100 MB CSV-Datei in 1,5 sec komplett zu durchforsten

die funktion muss also raus:

Delphi-Quellcode:
  Procedure _AddString;
  Var
    sTmp: String;

  Begin
    SetString(sTmp,ptrSubStr,Integer(ptrText) - Integer(ptrSubStr));
    aItems.Add(sTmp)
  End;

neue Variante:

Delphi-Quellcode:
Procedure TStringDivider.Explode(Const aText: String; aItems: TStrings);
Var
  ptrSubStr,ptrText,ptrTextEnd: PChar;
  sTmp: String;
Begin
  If length(fPattern) > 1 Then
    QSExplode(aText,aItems)
  Else Begin
    aItems.clear;
    ptrText := PChar(@aText[1]);
    ptrSubStr := ptrText;
    ptrTextEnd := PChar(@aText[Length(aText)]);
    inc(ptrTextEnd);
    Repeat
      If ptrText^ = fPatternFirstChar Then Begin

        SetString(sTmp,ptrSubStr,Integer(ptrText) - Integer(ptrSubStr));
        aItems.Add(sTmp);

        inc(ptrText);
        ptrSubStr := ptrText;
      End
      Else
        inc(ptrText);
    Until Integer(ptrText) = Integer(ptrTextEnd);

    SetString(sTmp,ptrSubStr,Integer(ptrText) - Integer(ptrSubStr));
    aItems.Add(sTmp);


  End;
End;
Hier mal ein Performancevergleich:
Alte Variante:
-------------------
Using TStringDivider in TStringList
100 chars per line: 1000000 lines in 2907 tics, 343997 lines per sec, 33,6 mb/s (del = ";")
100 chars per line: 1000000 lines in 1297 tics, 771010 lines per sec, 75,3 mb/s (del = "<Foobar>")
100 chars per line: 1000000 lines in 2187 tics, 457247 lines per sec, 44,7 mb/s (del = "ABCDE")
10000 chars per line: 50000 lines in 3781 tics, 13224 lines per sec, 129,1 mb/s (del = ";")
10000 chars per line: 50000 lines in 1422 tics, 35162 lines per sec, 343,4 mb/s (del = "<Foobar>")
10000 chars per line: 50000 lines in 2188 tics, 22852 lines per sec, 223,2 mb/s (del = "ABCDE")
1000000 chars per line: 500 lines in 3281 tics, 152 lines per sec, 148,8 mb/s (del = ";")
1000000 chars per line: 500 lines in 1047 tics, 478 lines per sec, 466,4 mb/s (del = "<Foobar>")
1000000 chars per line: 500 lines in 1718 tics, 291 lines per sec, 284,2 mb/s (del = "ABCDE")

Neue Variante:
-----------------
100 chars per line: 1000000 lines in 2219 tics, 450653 lines per sec, 44,0 mb/s (del = ";")
100 chars per line: 1000000 lines in 1359 tics, 735835 lines per sec, 71,9 mb/s (del = "<Foobar>")
100 chars per line: 1000000 lines in 2172 tics, 460405 lines per sec, 45,0 mb/s (del = "ABCDE")
10000 chars per line: 50000 lines in 2234 tics, 22381 lines per sec, 218,6 mb/s (del = ";")
10000 chars per line: 50000 lines in 1438 tics, 34771 lines per sec, 339,6 mb/s (del = "<Foobar>")
10000 chars per line: 50000 lines in 2219 tics, 22533 lines per sec, 220,0 mb/s (del = "ABCDE")
1000000 chars per line: 500 lines in 1875 tics, 267 lines per sec, 260,4 mb/s (del = ";")
1000000 chars per line: 500 lines in 984 tics, 508 lines per sec, 496,2 mb/s (del = "<Foobar>")
1000000 chars per line: 500 lines in 1735 tics, 288 lines per sec, 281,4 mb/s (del = "ABCDE")



30% Performancezuwachs (del = ";") - 100 chars per line: 1000000 lines
70% Performancezuwachs (del = ";") - 10000 chars per line: 50000 lines
75% Performancezuwachs (del = ";") - 1000000 chars per line: 500 lines
Phantasie ist etwas, was sich manche Leute gar nicht vorstellen können.
  Mit Zitat antworten Zitat