私は、Web アプリケーションのカスタム テンプレート システムの一部として頻繁に使用される C# 正規表現を使用してきました。式は複雑ですが、Regex.Compiled オプションを使用すると実際にパフォーマンスが向上することに気付きました。ただし、コンパイルの初期コストは、開発中、特に反復単体テスト中にイライラします (この一般的なトレードオフについては、こちらで説明しています)。
私が現在試している解決策の 1 つは、遅延正規表現コンパイルです。アイデアは、正規表現のコンパイル済みバージョンを別のスレッドで作成し、準備ができたらそれをサブすることで、両方の世界を最大限に活用できるということです。
私の質問は次のとおりです。これが悪い考えのパフォーマンスである理由やその他の理由はありますか? ジッティングやアセンブリのロードなどのコストをスレッド間で分散することが本当に機能するかどうかわからないため、質問します (私のベンチマークからはそう見えますが)。コードは次のとおりです。
public class LazyCompiledRegex
{
private volatile Regex _regex;
public LazyCompiledRegex(string pattern, RegexOptions options)
{
if (options.HasFlag(RegexOptions.Compiled)) { throw new ArgumentException("Compiled should not be specified!"); }
this._regex = new Regex(pattern, options);
ThreadPool.QueueUserWorkItem(_ =>
{
var compiled = new Regex(pattern, options | RegexOptions.Compiled);
// obviously, the count will never be null. However the point here is just to force an evaluation
// of the compiled regex so that the cost of loading and jitting the assembly is incurred here rather
// than on the thread doing real work
if (Equals(null, compiled.Matches("some random string").Count)) { throw new Exception("Should never get here"); }
Interlocked.Exchange(ref this._regex, compiled);
});
}
public Regex Value { get { return this._regex; } }
}