.net2.0中的正则表达式的RegexOptions.Compiled选项
99%的情况下没必要多加一个RegexOptions.Compiled选项
而编译后带来的匹配速度提升多数情况下可以忽律不计。
//==============================
如下生成实例
Regex regExp = new Regex(@"\$List:\{(.*)\}\$", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
使用RegexOptions.Compiled时启动速度明显很慢,
如要使用建议将regExp声明成static(全局对象),或者缓存起来,也可以直接使用Regex类方法如:
Match match=Regex.Match(input, @"\$List:\{(.*)\}\$", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled ); 使用Regex的静太方法时正则表达式将被缓存起来
避免如下写法
public string MyReplace(string input){
Regex regExp = new Regex(@"\$List:\{(.*)\}\$", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
return regExp.Replace(....)
}
参考文章内容:
来自:http://it.dianping.com/regexoptions-compiled.htm
//==============================================
曾经一位同事在写程序时发现在利用正则表达式匹配文本时的效率很低。首先可以排除是正则表达式本身的问题,因为所使用的正则表达式是十分简单的,匹配的文本量也不算大。检查的时候去掉了RegexOptions.Compiled的选项之后,程序整体速度得到了很大的提升。
这是因为误解了RegexOptions.Compiled这个选项提供的功能。在正则引擎启动正则表达式之前,需要做一些准备工作,这些准备工作包括检查正则表达式是否符合格式规范,并将其转化能够实际应用的内部形式。在许多关于正则表达式的文档中,将这一过程用compile来描述。然而在.NET中,这个过程实际上是以parsing来描述的。
在.NET中,parsing是指在程序执行过程中,第一次遇到正则表达式时必须检查它是否格式规范,并将其转换为适于.NET正则引擎实际应用的内部形式。
当指定RegexOptions.Compiled的时候,所提供的机制是告诉正则引擎,除了将正则表达式转换为认定的内部形式外,还将其编译(很多人会混淆这里的编译和parsing的过程)为底层的MSIL(Microsoft Intermediate Language)代码,在正则表达式实际应用时,可以由JIT(Just-In-Time)优化为更快的本地机器代码。
启动这个选项究竟对性能产生了怎样的影响,可以从三个方面来看。
首先在启动速度上,在不使用RegexOptions.Compiled会比较快,使用了RegexOptions.Compiled情况下,通常会使启动速度慢许多,据说最多是60倍。
在内存占用方面,使用RegexOptions.Compiled时,通常每个表达式会占用5KB~15KB的内存,更重要的是,在程序执行过程中,这块内存是无法被释放的。这里有时会带来一些问题,因为Regex在.NET中作为对象被封装,如果是多个进程或请求同时调用到这个代码片段,可能会造成相同的正则表达式在重复占用了内存,这取决于程序具体的实现方式。
在匹配速度方面,RegexOptions.Compiled是可以提升匹配速度的,但是因为有在启动速度和内存占用方面带来的额外开销,所以除非是在需要匹配大量的文本和反复使用某正则表达式时,这种提升非常不明显,而且在许多人误用此选项的情况下,得到的结果反而是程序整体运行速度的下降。所以在非大量文本处理的情况下,如果对程序整体效率有严格要求,建议不要使用该选项。
如果需要使用该选项,那么一个应该考虑的也是更好的方案应该是将要使用的正则对象封装到一个DLL中,这将使最终的程序占用的内存更少,因为不必装载使用RegexOptions.Compiled编译正则表达式的包。另外,由于在封装DLL时正则表达式已经编译好了,装载的速度也就得到了提升。附带的一个好处就是这个包还可以提供给其他需要的程序员调用,而不是copy正则表达式的代码。