Powershell: Combining the -replace operator with a lookbehind assertion slowed down by a factor of 30+ between v6.0.2 and v6.1.0-preview.2

Created on 2 Jun 2018  路  4Comments  路  Source: PowerShell/PowerShell

Note: I have not tried to analyze whether the problem is in PowerShell or CoreFx; on the PowerShell side, new features were recently added to -replace - see #6029 - but I have no idea whether this symptom relates to that.

The problem appears to be specific to -replace; using -match does not exhibit the symptom.

Steps to reproduce

Run the following command line:

  • first on v6.0.2 (the current stable release as of this writing).

  • then on v6.1.0-preview.2 (the current preview release).

$arr =  (, 'fooo') * 1e6; (Measure-Command { $arr -replace '(?<=.{3}).+' }).TotalSeconds

Expected behavior

Similar timings.

Actual behavior

Here are sample timings, in seconds, from a Windows 10 VM:

# v6.0.2
1.8444752

# v6.1.0-preview.2
# !! more than 30 times slower
61.5428622

Environment data

PowerShell Core v6.0.2
PowerShell Core v6.1.0-preview.2
Resolution-Fixed WG-Engine

Most helpful comment

Well, that's an unfortunate perf regression. You'd think that the PR could treat a replacement string the way it originally worked and only invoke the new code if replacement is of type scriptblock.

All 4 comments

@mklement0 this is a great find. I did a private build reverting the change in #6029 and the same test on my macBook went from 35.6s to 1.4s so that PR is causing this perf degradation.

Well, that's an unfortunate perf regression. You'd think that the PR could treat a replacement string the way it originally worked and only invoke the new code if replacement is of type scriptblock.

Note: the regression is not related to the actual regex, the operator was slow for any replacement string because it went through a very expensive path testing for MatchEvaluator before defaulting to string.

Closed via #7135

Was this page helpful?
0 / 5 - 0 ratings