我有一个大而复杂的C#正则表达式,在解释运行时可以正常工作,但速度有点慢。我正在尝试通过设置RegexOptions.Compiled
来加快速度,第一次大约需要30秒钟,之后立即完成。我正在尝试通过首先将正则表达式编译为程序集来消除这种情况,以使我的应用程序尽可能快。
我的问题是当编译延迟发生时,无论它是否在应用程序中编译:
Regex myComplexRegex = new Regex(regexText, RegexOptions.Compiled);
MatchCollection matches = myComplexRegex.Matches(searchText);
foreach (Match match in matches) // <--- when the one-time long delay kicks in
{
}
或者提前使用Regex.CompileToAssembly:
MatchCollection matches = new CompiledAssembly.ComplexRegex().Matches(searchText);
foreach (Match match in matches) // <--- when the one-time long delay kicks in
{
}
这使得将编译转换为汇编基本上是无用的,因为我仍然在第一个
foreach
调用上遇到延迟。我想要的是所有编译延迟都在编译时完成(在Regex.CompileToAssembly调用时),而不是在运行时完成。我错在哪里了?(我用来编译成程序集的代码类似于http://www.dijksterhuis.org/regular-expressions-advanced/,如果相关的话)。
编辑:
在
new CompiledAssembly.ComplexRegex().Matches(searchText);
中调用编译后的程序集时,我应该使用new
吗?但如果没有它会出现"需要对象引用"错误。更新2
感谢答案/评论。我使用的正则表达式非常长,但基本上很简单,是由数千个单词列表组成,每个单词之间用|分隔。我真的看不出这会是一个回溯问题。主题字符串可能只有一个字母长,它仍然会导致编译延迟。对于一个RegexOptions.Compiled正则表达式,当正则表达式包含5000个单词时,执行需要超过10秒钟。相比之下,正则表达式的未编译版本可以拥有30,000多个单词,并且仍然几乎立即执行。
经过大量测试后,我认为我发现了以下内容:
- 当您的正则表达式有许多替代方案时,请不要使用RegexOptions.Compiled——编译可能非常缓慢。
- .Net会在可能的情况下使用惰性评估来进行正则表达式匹配,至少在某种程度上,我认为这也适用于正则表达式编译。只有在必须时,正则表达式才会被完全编译,似乎没有办法提前强制编译。
- 如果可以强制正则表达式完全编译,Regex.CompileToAssembly将更加有用,因为它现在几乎是无意义的。
如果我错了或漏了什么,请纠正我!