Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TPerlRegex sehr langsam (https://www.delphipraxis.net/149302-tperlregex-sehr-langsam.html)

luke2 18. Mär 2010 13:06


TPerlRegex sehr langsam
 
Hallo,

Kennt jemand von euch TPerlRegex?

Ich benutze es so:
Delphi-Quellcode:
  with TPerlRegEx.Create(nil) do try
    Subject := sFileContent;
    RegEx := '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
    //Options := [preMultiLine];
    //Compile;
    Result := Match;
    if Result then
      repeat
        sl.Add(MatchedExpression);
      until not MatchAgain;
  finally
    Free;
  end;
Als Subject wird der Inhalt einer gerade mal 600KB großen Textdatei angegeben und es werden ungefähr 30000 Strings gefiltert.
Dieser Vorgang dauert gefühlte 30 Sekunden. Muss man da etwas beachten oder wieso ist das so langsam?

Ich verwende die Testversion von Delphi2010.

mirage228 18. Mär 2010 13:10

Re: TPerlRegex sehr langsam
 
Ich könnte mir vorstellen, dass hier versucht wird Patterns öfter zu matchen: http://de.php.net/manual/de/regexp.r...e.onlyonce.php

Versuchs mal so:
Code:
(?>\d{1,3})\.(?>\d{1,3})\.(?>\d{1,3})\.(?>\d{1,3})
oder du versuchst es mit Assertions:
Code:
(\d{1,3}(?=\.)){3}\d{1,3}
Edit: Die Ausdrücke sind ungetestet. Sollten aber prinzipiell zumindest so funktionieren.

Viele Grüße

luke2 18. Mär 2010 13:17

Re: TPerlRegex sehr langsam
 
Danke für die Vorschläge.
Der erste Ausdruck funktioniert, dauert aber genau so lange wie meiner; der zweite geht zwar recht schnell, liefert aber leider keine Matches.

Die Seite ist leider gerade nicht erreichbar.

Hawkeye219 18. Mär 2010 13:24

Re: TPerlRegex sehr langsam
 
Hallo luke2,

ist sl eine einfache Stringliste, oder verweist die Variable auf eine sichtbare Komponente (Memo o.ä.)? Im letzten Fall sollte es helfen, das Füllen der Liste mit den Methoden Delphi-Referenz durchsuchenBeginUpdate und Delphi-Referenz durchsuchenEndUpdate zu klammern.

Gruß Hawkeye

luke2 18. Mär 2010 13:29

Re: TPerlRegex sehr langsam
 
Hallo Hawkeye,

Es ist eine einfache Stringliste, auch nicht sortiert oder so.
Ich habe die Zeile mit dem sl.add() auch einmal auskommentiert, brachte aber keine Änderung.

Es muss der Aufruf von MatchAgain sein, der so langsam ist, aber leider habe ich den Quellcode nicht, um nachzuschauen, was dort passiert. :?

s.h.a.r.k 18. Mär 2010 13:57

Re: TPerlRegex sehr langsam
 
Hallo,

geh mal auf Nummer sicher und teste die Geschwindigkeit wie folgt:
Delphi-Quellcode:
var
  blub : Int64;
begin
{... }
blub := GetTickCount();
Result := Match;
if Result then
  repeat
    //sl.Add(MatchedExpression);
  until not MatchAgain;
blub := GetTickCount() - blub;
ShowMessage(IntToStr(blub) + ' Millisekunden);
Ansonsten kannst auch mal die Lib testen: http://www.regular-expressions.info/delphi.html

luke2 18. Mär 2010 14:11

Re: TPerlRegex sehr langsam
 
Das ergibt einen Wert von 24960 = 25 Sekunden, das ist - finde ich - für 600KB Daten einfach zu langsam!
Diese Komponente basiert doch auch auf der pcre.dll und kapselt nur die Aufrufe, deshalb verstehe ich nicht, wieso das so langsam ist :?:

mirage228 18. Mär 2010 14:11

Re: TPerlRegex sehr langsam
 
Zitat:

Zitat von luke2
Danke für die Vorschläge.
Der erste Ausdruck funktioniert, dauert aber genau so lange wie meiner; der zweite geht zwar recht schnell, liefert aber leider keine Matches.

Die Seite ist leider gerade nicht erreichbar.

So gings mit meiner PCRE library (verwendet auch die pcre.dll, daher sollten die Ergebnisse auch gleich sein):
Code:
(\d{1,3}(?>\.)){3}(?>\d{1,3})
Match kam erfolgreich zurück. Sollte so auch relativ schnell sein.

Schau mal, ob das bei dir die richtigen Matches liefert.

Viele Grüße

luke2 18. Mär 2010 14:17

Re: TPerlRegex sehr langsam
 
Dieser Ausdruck liefert mir die korrekten Matches dauert aber wieder um die 20 Sekunden. :|

Wie hast du die pcre.dll denn eingebunden? dieses TPerlRegEx bindet es statisch ein, so dass die dll von der Anwendung nicht mehr benötigt wird.
Aber mit der Geschwindigkeit kann das doch nichts zu tun haben, oder?

mirage228 18. Mär 2010 14:19

Re: TPerlRegex sehr langsam
 
Ich verwende: http://www.renatomancuso.com/software/dpcre/dpcre.htm
Allerdings auf D2010 angepasst (string->AnsiString, PChar->PAnsiChar, PCRE 6.7 Lib pcre.dll - muss der Anwendung beigelegt werden).

Lade mal die Test-Datei (also dort wo die gesuchten Einträge drin sind) hoch, dann kann ich genauere Geschwindigkeitstests machen ...

Viele Grüße

luke2 18. Mär 2010 14:29

Re: TPerlRegex sehr langsam
 
Liste der Anhänge anzeigen (Anzahl: 1)
OK, Danke mach ich. Wenn das damit echt schneller geht, schmeiss ich das Perl Dings runter und mache es damit. :wink:

mirage228 18. Mär 2010 15:23

Re: TPerlRegex sehr langsam
 
Der obige Regex braucht hier nicht mal eine Sekunde (Das Schreiben ins Memo dauert aber ein paar Sekunden):
Delphi-Quellcode:
var
  M: IMatchCollection;
  N: TStringList;
  i: Integer;
begin
  N := TStringList.Create;
  with TStringList.Create do
  try
    LoadFromFile('ips.txt');
    with RegExCreate('(\d{1,3}(?>\.)){3}(?>\d{1,3})') do
    begin
      M := Matches(Text);
      for i := 0 to M.Count - 1 do
        N.Add(M.Items[i].Value)
    end;
    Memo1.Lines.Assign(N);
  finally
    Free;
    N.Free;
  end;
Hast Du nicht so etwas wie eines "Matches" Funktion bei TPerlRegEx, die alle Resultate auf einmal liefert?

Viele Grüße

luke2 18. Mär 2010 15:36

Re: TPerlRegex sehr langsam
 
OK, Danke. Kannst du die von dir umgeschrieben Unit für Delphi2010 evtl. noch kurz anhängen? Dann tausche ich das direkt in meinem Projekt aus. :)

mirage228 18. Mär 2010 20:01

Re: TPerlRegex sehr langsam
 
Moin,

Ich weiß grad nicht wie das Lizenz-technisch mit der Weitergabe der modifizierten Dateien aussieht, müsste ich morgen oder so mal schauen.

Aber die Konvertierung war echt simpel. Einfach alle Typen wie genannt ersetzt - sollte nicht länger als 30 Minuten dauern. Beispiele zur Verwendung der Unit findest Du übrigens in meinem PHP Inspektor-Projekt (siehe Link in der Signatur, da ist allerdings noch die alte DLL/Units der Bib dabei)...

Viele Grüße

luke2 18. Mär 2010 20:36

Re: TPerlRegex sehr langsam
 
Das wäre nett, wenn nicht wäre das auch nicht so schlimm, dann bastle ich mir das selbst zusammen. :)

Jedenfalls danke für die Hilfe.

himitsu 13. Apr 2010 08:43

Re: TPerlRegex sehr langsam
 
Zitat:

Zitat von luke2
Diese Komponente basiert doch auch auf der pcre.dll und kapselt nur die Aufrufe, deshalb verstehe ich nicht, wieso das so langsam ist :?:

Die pcre.dll kann nur Ansi/UTF-8 und dein Delphi ist Unicode,
da kommen dann noch einige UTF-8<->Unicode-Umwandlungen mit rein, aber so sehr sollten diese auch nicht ausbremsen, falls sie richtig platziert sind. :gruebel:

Oder wurde diese TPerlRegex im D2009/D2010-Port nur auf Ansi begrenzt? (hab noch nicht nachgesehn)

Aktuell kann eigentlich keine Lib nativ mit Unicode umgehn.

(selbst wenn es eine Ansi-Datei ist, wird dieser über die StringList nach Unicode umgewandelt)

@mirage228:
Wenn es eine OpenSource-Lib ist und man frei an die (Original)-Quellcodes rankommt, dann sollte es keine Probleme geben. Es müßte nur erwähnt werden, das es kein Original ist.

Oder du gibts nur eine Änderungsanweisung raus und jeder ändert es sich selber.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:52 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz