.NET Core 2.1 - Regex в цикле 200x медленнее, чем 2.0 (3x в простой тесте)

У меня есть следующее регулярное выражение:

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

Он работает на ~ 1000 строк (вызов IsMatch). В.NET Core 2.0 он занимает около 10 10ms. После перехода на.NET Core 2.1 он занимает более 2 seconds по тем же данным.

Любая идея, что происходит? Любое изменение поведения в 2.1?

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

Обновление: BenchmarkDotNet

Воспроизводимое 3- netcoreapp2.1 падение (просто запустите, измените netcoreapp2.1 на netcoreapp2.0 в csproj, запустите снова). https://github.com/ptupitsyn/netcore2.1-regex-perf/tree/master/src

  • Упрощение фактического применения в максимально возможной степени уменьшило падение, но оно все еще очень заметно.
  • Перевертывание вложенных циклов в GetPackageInfos2 уменьшает первенство до 25%, но оно все еще существует. Изменение этого кода в реальном мире не является тривиальным, и я бы хотел избежать такого рефакторинга.
  • Есть несколько RegEx, выполненных в цикле, и я не смог воспроизвести падение только с одним RegEx

Обновление 2

Удаление RegexOptions.Compiled решает проблему!

Ответы

Ответ 1

RegexOptions.Compiled не реализован в.NET Core 2.0, но реализован в.NET Core 2.1.

Компиляция включает первоначальные накладные расходы, а для определенных моделей использования эти накладные расходы перевешивают прибыль от скомпилированного регулярного выражения.

Мой случай несколько сложный, и кажется, что в.NET может быть ошибка, потому что даже с надлежащим эталоном (с разминкой) режим Compiled работает медленнее. См. Подробности в выпуске Corefx: https://github.com/dotnet/corefx/issues/30131