Einzelnen Beitrag anzeigen

Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#13

AW: Effizientes Einlesen und Verarbeiten von Textdatei

  Alt 2. Jul 2022, 19:02
Nach ein paar Tests mit TStopwatch und einer absichtlich großen PEM-Datei (etwas über 1 MiB) stelle ich Folgendes fest:
  1. Das Problem ist nicht so groß wie es anfänglich schien. Externe Speicherlecksucher schauen eben genauer hin, was seine Zeit braucht. Das hat mich glauben lassen, die Implementation an sich wäre langsam. Naja, im Vergleich mit anderen ist sie das auch, siehe nächster Punkt
  2. Der Weg mit dem Löschen der Strings ist trotzdem langsamer ist als Hochzählen eines Index

Das Verarbeiten der Textdatei (nach LoadFromFile!) mittels Löschen von Strings - siehe OP - dauert um die 200ms, mit dem Hochzählen des Index nur zwischen ca. 20 und 40ms.

Ich habe mich nun für das Hochzählen des Index mit folgender Implementation entschieden:
Delphi-Quellcode:
procedure NameNotRelevant;
var
  Lsl: TMyStringList;
  LidxH, LidxF: integer;
  Lheaderpresent: Boolean;
  Lstr: string;
begin
    Lsl:= TMyStringList.Create;
    try
      Lsl.LoadFromFile(FFileName);
      LidxF:= 0;
      Lheaderpresent:= False;
      repeat
          LidxH:= Lsl.IndexOf(PEM_HEADER, LidxF);
          LidxF:= Lsl.IndexOf(PEM_FOOTER, LidxF+1);
          if LidxH < 0 then begin
            if NOT Lheaderpresent then
                NameNotRelevant2(Lstr);
          end else begin
            Lheaderpresent:= True;
            Lstr:= Trim(Lsl.StringsBetween(LidxH+1, LidxF-1));
            NameNotRelevant2(Lstr);
            Inc(LidxF);
          end;
      until LidxH < 0;
    finally
      Lsl.Free;
    end;
end;

procedure NameNotRelevant2(const ACertStr: string);
var
  Lblob: CERT_BLOB;
begin
    if Length(ACertStr) = 0 then Exit;
    Lblob.cbData:= Length(ACertStr) * SizeOf(Char);
    GetMem(Lblob.pbData);
    try
      Move(ACertStr[1], Lblob.pbData^, Lblob.cbData);
      // Do something with Lblob
    finally
      FreeMem(Lblob.pbData);
    end;
end;
IndexOf hab ich frecherweise aus dem Quellcode von TStrings.IndexOf kopiert und lediglich einen Parameter ergänzt:
Delphi-Quellcode:
function TMyStringList.IndexOf(const S: string; StartIndex: integer): integer;
begin
  for Result := StartIndex to GetCount - 1 do
    if AnsiCompareText(Get(Result), S) = 0 then Exit;
  Result := -1;
end;
Wieso gibt's davon eigentlich standardmäßig keine solche Überladung?

-----

Wenn jemand eine schnellere Variante hat, kann die gern gepostet werden.

Auf alle Fälle danke ich allen Postern für die rege Beteiligung!

Grüße
Dalai
  Mit Zitat antworten Zitat