.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