2013-03-14 24 views
1

我一直在使用C#正则表达式,它在Web应用程序中作为自定义模板系统的一部分大量使用。该表达式很复杂,我注意到使用Regex.Compiled选项会带来真正的性能提升。然而,编译的初始成本在开发过程中很刺激,尤其是在迭代单元测试期间(这种总体折衷被提到here)。在单独的线程中编译.NET正则表达式

我目前正在尝试的一种解决方案是懒惰正则表达式编译。我的想法是,我可以通过在单独的线程中创建正则表达式的编译版本并在准备就绪时将其置于其中,从而充分发挥两全其美。

我的问题是:是否有任何理由为什么这可能是一个糟糕的主意表现或其他?我问,因为我不确定是否分配线程中的事件成本和装配加载的成本真的有效(尽管它似乎来自我的基准测试)。 下面的代码:

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; } } 
} 
+1

为什么不使用'懒惰'? – leppie 2013-03-14 12:33:16

+0

你能不能以某种方式利用现有的Regex缓存? http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.cachesize.aspx – spender 2013-03-14 12:33:51

+0

说实话,这可能更适合[codereview](http://codereview.stackexchange.com/ ) – hometoast 2013-03-14 12:33:57

回答

6

这听起来像你想使用Regex.CompileToAssembly作为一个编译时间步长。

+0

没错。打败我吧。 – 2013-03-14 13:17:22

+0

有没有一种简单的方法可以将它添加到构建过程中,同时仍然允许我轻松地迭代我的正则表达式(例如,为我们的模板语言添加功能)? – ChaseMedallion 2013-03-14 13:21:46

+1

@ChaseMedallion:您可以编写一个小命令行应用程序,并将其作为构建前/构建步骤的一部分。 – leppie 2013-03-14 13:27:11