【问题标题】:.NET Core 2.1 - Regex in loop 200x slower than 2.0 (3x in simple benchmark).NET Core 2.1 - 循环中的正则表达式比 2.0 慢 200 倍(简单基准测试中的 3 倍)
【发布时间】:2018-06-04 10:34:09
【问题描述】:

我有以下正则表达式:

    var regex = new Regex(
        @"^ActiveMQ[\d\.-]*$",
        RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

它运行了大约 1000 个字符串(IsMatch 调用)。在 .NET Core 2.0 中,它大约需要 10ms。迁移到 .NET Core 2.1 后,它会在相同数据上接管 2 seconds

知道发生了什么吗? 2.1 中的行为有何变化?

=======================

更新:BenchmarkDotNet

可重现的 3 倍下降(只需运行,将 csproj 文件中的 netcoreapp2.1 更改为 netcoreapp2.0,再次运行)。 https://github.com/ptupitsyn/netcore2.1-regex-perf/tree/master/src

  • 尽可能简化实际应用,降低了跌幅,但它 仍然非常明显。
  • 翻转GetPackageInfos2 中的嵌套循环可将性能下降减少到仅25%,但它仍然存在。在实际代码中更改这一点并非易事,我想避免这种重构。
  • 在一个循环中执行了多个 RegEx,我无法仅使用一个 RegEx 来重现 drop

更新 2

删除RegexOptions.Compiled 即可解决问题!

【问题讨论】:

  • 你如何测试这个?
  • 我在一些真实世界的应用程序上使用分析器。我还将创建一个简单的复制器。 @CamiloTerevinto
  • 使用BenchmarkDotNet 获得可重现的基准会有所帮助。比较 GC 和 IL 结果以查看问题是由于不同的Regex 代码还是 JIT 问题。 (Regex 问题将是 CoreFX,JIT 问题将是 CoreCLR。)
  • 我能够重现您的发现。人们不会期望编译的正则表达式在 2.1 中 match 更慢,因此我认为您发现了一个错误。 Please report it on GitHub here。谢谢。

标签: c# regex .net-core


【解决方案1】:

RegexOptions.Compiled 在 .NET Core 2.0 中未实现,但在 .NET Core 2.1 中已实现

编译涉及初始开销,对于某些使用模式,此开销超过编译正则表达式的收益。

我的情况有点复杂,而且似乎 .NET 中可能存在错误,因为即使使用适当的基准测试(带有预热),Compiled 模式也会更慢。请参阅 Corefx 问题中的详细信息:https://github.com/dotnet/corefx/issues/30131

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 2015-08-30
  • 1970-01-01
相关资源
最近更新 更多