Warum ist meine regex so viel langsamer kompiliert als interpretiert?

Ich habe eine große und komplexe C# regex läuft OK, wenn Sie interpretiert wird, aber ist ein bisschen langsam. Ich versuche, speed-up durch die Einstellung RegexOptions.Compiled, und das scheint in 30 Sekunden zum ersten mal, und sofort danach. Ich bin versucht zu negieren, dies durch kompilieren der regex zu einer ersten Versammlung, so dass meine app so schnell wie möglich.

Mein problem ist, wenn die Erstellung Verzögerung erfolgt, ob es kompiliert in der app:

Regex myComplexRegex = new Regex(regexText, RegexOptions.Compiled);
MatchCollection matches = myComplexRegex.Matches(searchText);
foreach (Match match in matches) //<--- when the one-time long delay kicks in
{

} 

oder mit Regex.CompileToAssembly im Voraus:

MatchCollection matches = new CompiledAssembly.ComplexRegex().Matches(searchText);
foreach (Match match in matches) //<--- when the one-time long delay kicks in
{

} 

Dadurch wird die Kompilierung einer assembly im Grunde nutzlos, da ich immer noch die Verzögerung auf die erste foreach nennen. Was ich will, ist für alle kompilieren Verzögerung getan werden zur compile-Zeit statt (an der Regex.CompileToAssembly nennen), und nicht zur Laufzeit. Wo mache ich falsch ?

(Der code, den ich verwende, um zu kompilieren, um eine Montage ist ähnlich http://www.dijksterhuis.org/regular-expressions-advanced/ , falls das relevant ist ).

Edit:

Soll ich mich mit new beim Aufruf der kompilierten assembly in new CompiledAssembly.ComplexRegex().Matches(searchText); ? Es gibt ein "Objektverweis erforderlich" - Fehler, ohne es aber.

Update 2

Danke für die Antworten/Kommentare. Die regex, die ich verwende, ist ziemlich lang, aber im Grunde einfach, eine Liste von tausenden von Wörtern, jeweils durch | getrennt. Ich kann nicht sehen, es wäre ein backtracking problem wirklich. Die Zeichenkette kann nur einen Buchstaben lang und es kann noch verursachen die Zusammenstellung Verzögerung. Für ein RegexOptions.Zusammengestellt regex, es dauert über 10 Sekunden ausgeführt werden, wenn die regex enthält 5000 Wörter. Zum Vergleich die nicht-kompilierte version der regex nehmen kann, mit 30.000+ Wörter-und immer noch ausführen, nur um sofort.

Nachdem ich eine Menge Tests, die auf dieser, ich denke, was ich herausgefunden habe ist:

  • Nicht verwenden, RegexOptions.Kompiliert wenn dein regex hat viele alternativen - es kann extrem langsam sein, um zu kompilieren.
  • .Net verwenden lazy evaluation für regex, wenn möglich, und AFAI sehen kann, dieses erstreckt sich (zumindest teilweise) zu regex-Kompilierung zu. Ein regex vollständig kompiliert nur, wenn es sein muss, und es scheint keinen Weg zu zwingen, Zusammenstellung vor der Zeit.
  • Regex.CompileToAssembly wäre viel nützlicher, wenn die regexes könnte gezwungen sein, vollständig zusammengestellt, es scheint zu sein, gesteigert wird sinnlos, wie es ist.

Bitte korrigieren Sie mich, wenn ich falsch bin oder etwas fehlt!

  • Vielleicht sollten Sie versuchen, auf die tatsächliche expression beteiligt und ein Beispiel für die Eingabe, die Ihnen dieses Verhalten.
  • Vielen Dank für diesen Beitrag. Hatte das gleiche Problem mit einigen Regex von Twitter portiert von Java nach .NET. Beide RegexOptions.Zusammengestellt und .CompileToAssembly verursacht die Anwendung nicht mehr reagiert für ~10 Sekunden beim ersten mal, wenn er versucht zu entsprechen. Entfernt die Regex.Kompiliert und alles ist instant.
  • MSDN Hinzugefügt, "best practices" -Artikel .NET 4 die angesprochen, regex zusammengestellt, die sich zu Baugruppen.
InformationsquelleAutor mikel | 2010-12-27
Schreibe einen Kommentar