|
曾经一位同事在写程序时发现在利用正则表达式匹配文本时的效率很低。首先可以排除是正则表达式本身的问题,因为所使用的正则表达式是十分简单的,匹配的文本量也不算大。检查的时候去掉了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正则表达式的代码。
以上内容和分析适用于.NET Framework 2.0。
NET技术:RegexOptions.Compiled的含义和使用,转载需保留来源!
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。