Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Core 2.1 - Regex in loop 200x slower than 2.0 (3x in simple benchmark)

I have the following regex:

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

It runs over ~1000 strings (IsMatch call). In .NET Core 2.0 it takes around 10ms. After migrating to .NET Core 2.1 it takes over 2 seconds on the same data.

Any idea what's going on? Any behavior changes in 2.1?

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

Update: BenchmarkDotNet

Reproducible 3x drop (just run, change netcoreapp2.1 to netcoreapp2.0 in csproj file, run again). https://github.com/ptupitsyn/netcore2.1-regex-perf/tree/master/src

  • Simplifying actual application as much as possible has reduced the drop, but it is still very much visible.
  • Flipping the nested loops in GetPackageInfos2 reduces the perf drop to only 25%, but it is still there. Changing this in real-world code is not trivial and I would like to avoid this kind of refactoring.
  • There are multiple RegEx executed in a loop, and I could not reproduce the drop with only one RegEx

Update 2

Removing RegexOptions.Compiled solves the problem!

like image 916
Pavel Tupitsyn Avatar asked Jun 04 '18 10:06

Pavel Tupitsyn


1 Answers

RegexOptions.Compiled is not implemented in .NET Core 2.0, but is implemented in .NET Core 2.1.

Compilation involves initial overhead, and for certain usage patterns this overhead outweighs the gains of compiled regex.

My case is somewhat complex, and it seems like there might be a bug in .NET, because even with a proper benchmark (with warm-up), Compiled mode is slower. See details in Corefx issue: https://github.com/dotnet/corefx/issues/30131

like image 190
Pavel Tupitsyn Avatar answered Nov 01 '22 16:11

Pavel Tupitsyn