Neu in .NET 7.0 [27]: Leistung des Source-Generators für reguläre Ausdrücke
Ein Vergleich mit anderen Verfahren zeigt, wann es sich lohnt, den neuen Source-Generator für reguläre Ausdrücke zu verwenden.
- Dr. Holger Schwichtenberg
Das aktuelle .NET 7.0 bringt einen neuen Source-Code-Generator mit, den ich im vorigen Teil der Serie vorgestellt habe. Man kann ihn per Annotation nutzen, statt die Klasse RegEx
zu instanziieren:
public partial class Checker // Partielle Klasse
{
[GeneratedRegex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")]
// Partielle Methode, die dann von SG implementiert wird:
public partial Regex EMailRegEx();
}
In einem Leistungsvergleich (siehe Abbildung 1) sieht man, dass für die einmalige Ausführung eines regulären Ausdrucks der neue Source-Generator die schnellste Variante ist. Bei 100 wiederholten Nutzungen sieht die Sache etwas anders aus. Hier gewinnt die zur Laufzeit kompilierte Lösung klar, sofern das Kompilieren nur einmal erfolgt:
Regex re2;
public string ExtractEMail_ClassicCompiledPrepared(string input)
{
if (re2 == null) re2 =
new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",
RegexOptions.Compiled);
var m = re2.Match(input);
return m.Value;
}
Auch die interpretierte Variante ist schneller, wenn man das RegEx-Objekt nur einmal instanziiert:
Regex re1;
public string ExtractEMail_InterpretedPrepared(string input)
{
if (re1 == null) re1 =
new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");
return re1.Match(input).Value;
}
Beim Verwenden des Source-Generators macht es keinen großen Unterschied, ob man die Instanz der partiellen Klasse wiederverwendet oder immer wieder neu erzeugt, denn im generierten Code wird von dem regulären Ausdruck ein statisches Mitglied verwendet, wie Abbildung 1 zeigt.
.NET 7.0 verbessert die Leistung der regulären Ausdrücke auch beim Einsatz der Klasse RegEx
. Details erläutert Microsoft in einem Blogeintrag.
(rme)