mik*_*kel 19 c# regex performance
我有一个庞大而复杂的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
{
}
Run Code Online (Sandbox Code Playgroud)
或提前使用Regex.CompileToAssembly:
MatchCollection matches = new CompiledAssembly.ComplexRegex().Matches(searchText);
foreach (Match match in matches) // <--- when the one-time long delay kicks in
{
}
Run Code Online (Sandbox Code Playgroud)
这使得编译程序基本没用,因为我仍然在第一次foreach调用时遇到延迟.我想要的是所有的编译延迟都是在编译时完成的(在Regex.CompileToAssembly调用中),而不是在运行时.我哪里错了?
(我用来编译成程序集的代码类似于 http://www.dijksterhuis.org/regular-expressions-advanced/,如果相关的话).
编辑:
new在调用编译的程序集时我应该使用new CompiledAssembly.ComplexRegex().Matches(searchText);吗?但它没有提供"需要对象引用"错误.
更新2
谢谢你的回答/评论.我正在使用的正则表达式很长但基本上很简单,列出了数千个单词,每个单词用|分隔.我真的看不出这是一个回溯问题.主题字符串可以只有一个字母长,它仍然可以导致编译延迟.对于RegexOptions.Compiled正则表达式,当正则表达式包含5000个单词时,执行将需要10秒以上.为了比较,正则表达式的非编译版本可以使用30,000多个单词,并且仍然可以立即执行.
在对此进行了大量测试后,我认为我发现的是:
如果我错了或遗漏了什么,请纠正我!
使用时RegexOptions.Compiled,应确保重新使用Regex对象.看起来你好像不这样做.
RegexOptions.Compiled是一种权衡.正则表达式的初始构造将更慢,因为代码是即时编译的,但每个匹配应该更快.如果正则表达式在运行时更改,则使用RegexOptions.Compiled可能没有任何好处,尽管它可能取决于所涉及的实际表达式.
如果你的实际代码看起来像你发布的代码,那么你没有任何优势CompileToAssembly,因为每次运行这段代码时你都会创建新的,正在运行的Regex实例.为了利用CompileToAssembly,您需要先编译Regex; 然后获取生成的程序集并在项目中引用它.然后,您应该实例化生成的生成的强类型Regex类型.
在您链接到的示例中,他有一个名为FindTCPIP的正则表达式,它被编译为名为FindCTPIP的类型.当需要使用时,应该创建此特定类型的新实例,例如:
TheRegularExpressions.FindTCPIP MatchTCP = new TheRegularExpressions.FindTCPIP();
Run Code Online (Sandbox Code Playgroud)
尝试使用Regex.CompileToAssembly,然后链接到程序集,以便您可以构造 Regex 对象。RegexOptions.Compiled是一个运行时选项,每次运行应用程序时,正则表达式仍会重新编译。