Laden...

Regex Performance- und Ressourcenfrage

Erstellt von Bunnychecker vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.320 Views
B
Bunnychecker Themenstarter:in
224 Beiträge seit 2009
vor 13 Jahren
Regex Performance- und Ressourcenfrage

Hi.

Wenn ich aus einem Quelltext mittels Regex einen bestimmten Teil herausfiltern möchte, welche dieser Varianten ist dann resourcenschonender?

z.B. [php]"?id1=123&id2=456"[/php]

Ist es in solch einem Fall das beste, die Regex so genau wie möglich zu definieren?

Also:

@"test\.php\?id1=\d+&id2=\d+"

oder doch eher

@"test\.php\?[\w&=]+"

oder sollte man bei vielen verschiedenen Zeichen, die folgen dürfen, lieber das letzte Element ausschließen, sodass dadurch nur noch geprüft wird, ob das nächste Zeichen, jeweils nicht das ausgeschlossene ist.

Also:

@"test[^""]+"

Letzte Möglichkeit wäre meines Erachtens, die resourcenschonenste, ist aber nur eine Vermutung.

MfG Bunny

F
240 Beiträge seit 2006
vor 13 Jahren

Ich kann dir keine genauen Zahlen liefern, aber ich würde empfehlen, die patterns so zu schreiben, dass ersichtlich ist, was erreicht werden will. Das, was du versuchst, fiele unter den Bereich premature optimization. Regexes haben das Problem, dass sie zum Teil sehr schwer verständlich sind, und wenn man da nicht so klar wie möglich ist, ist es noch schwerer.

B
Bunnychecker Themenstarter:in
224 Beiträge seit 2009
vor 13 Jahren

Im allgemeinen kann ich sehr gut mit Pattern umgehen, es kommt mir halt wirklich auf die Performance an.

Vielleicht weiß irgendjemand wie Regex genauer funktioniert und man dadurch Aussagen darüber treffen kann, welche Methoden die schnellste/beste ist.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Bunnychecker,

in den drei Fällen wirst du in der Praxis vermutlich keinen einen Unterschied feststellen. Insofern stimme ich Femaref zu, dass es eine premature optimization wäre, den Pattern nach der Performance und nicht nach der Lesbarkeit zu schreiben.

Kritisch ist bei Regex ohnehin nur ausuferndes Backtracking, also wenn es viele verschiedene Wege gibt, einen Substring zu matchen, ohne dass der danach folgende Musterteil passt. Dann müssen alle diese unterschiedlichen Wege erfolglos probiert werden. Das wird in keinem der Fälle auftreten.

^(.+)(.+)x$ wäre so ein Fall für ein aufwändiges Backtracking, wenn der String, auf den gematcht werden soll, lang ist (also z.B. >10KB), keine Zeilenumbrüche enthält und am Ende des Strings kein x steht. Dann versucht Regex.Match alle möglichen Aufteilungen des Strings in Gruppe 1 und Gruppe 2 durch und scheitert bei jeder, weil am Ende kein x steht. Wenn man das ^ am Anfang entfernt, kann man den Aufwand noch mal erheblich steigern, weil dann das eben geschilderte Spiel für jede mögliche Anfangsposition durchgeführt wird. Dann reicht schon ein String von ein paar hundert Zeichen, um den Aufwand der Prüfung auf mehrere Sekunden zu treiben.

Aber solange mal solche Fallen nicht einbaut, muss man sich um die Performance von Regex keine Sorgen machen.

herbivore

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

passend zum Thema: Optimizing Regular Expression Performance, Part II: Taking Charge of Backtracking [Ron Petrusha] (und Part I - ist verlinkt im Artikel).

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"