C#Regex性能纯相对JS

dov*_*vid 6 .net javascript c# regex text-processing

我对正则表达式的速度有很好的体验JS.

我决定做一个小比较.我运行了以下代码:

var str = "A regular expression is a pattern that the regular expression engine attempts to match in input text.";

var re = new RegExp("t", "g");

console.time();

for(var i = 0; i < 10e6; i++)
   str.replace(re, "1");

console.timeEnd();
Run Code Online (Sandbox Code Playgroud)

结果:3888.731ms.

现在C#:

var stopwatch = new Stopwatch();

var str = "A regular expression is a pattern that the regular expression engine attempts to match in input text.";

var re = new Regex("t", RegexOptions.Compiled);

stopwatch.Start();

for (int i = 0; i < 10e6; i++)
    re.Replace(str, "1");

stopwatch.Stop();

Console.WriteLine( stopwatch.Elapsed.TotalMilliseconds);
Run Code Online (Sandbox Code Playgroud)

结果:32798.8756ms !!

现在,我尝试了re.exec(str);vs Regex.Match(str, "t");:1205.791ms VS 7352.532ms赞成JS.

大量的文字处理"不适合"有待完成.net吗?

UPDATE 1与[ta]模式相同的测试(而不是t文字):

3336.063ms in js VS 64534.4766 !!! 在c#中.

另一个例子:

console.time();

var str = "A regular expression is a pattern that the regular expression engine attempts 123 to match in input text.";


var re = new RegExp("\\d+", "g");
var result;
for(var i = 0; i < 10e6; i++)
    result = str.replace(str, "$0");


console.timeEnd();
Run Code Online (Sandbox Code Playgroud)

3350.230ms在JS,VS 32582.405ms在C#.

Imr*_*vel 3

String在 C# 中是一头危险的野兽,如果你不小心使用它,你真的可以搬起石头砸自己的脚,但我不认为给定的测试具有足够的代表性,不足以保证任何概括。

首先,我确实为您的测试用例重现了类似的性能。添加后,RegexOptions.Compiled所需时间减少到 30 秒左右,但这仍然是显着差异。

具体的测试用例可能不太现实,因为谁会使用正则表达式进行单个字符替换?如果您使用专用 API 来完成此任务,您将str.Replace('t', '1');在我的机器上获得 1600 毫秒的可比结果。

这意味着对于这个特定任务,C# 的性能与 JS 相当。C# 是否Regex.Replace()在内部以某种方式不适合单字符替换,或者 JS 正则表达式版本是否正在优化正则表达式 - 一些 JS 大师应该回答这个问题。

更现实的复杂正则表达式是否会有显着差异 - 了解会很有趣。

编辑: 我验证了当实际使用替换结果时以及每次运行中输入字符串不同时(在我的测试中为 10 秒与 35 秒),性能差距仍然存在。所以差距较小,但仍然存在。

可能的原因

根据这个 SO 问题的提示,浏览器实现将一些字符串操作委托给优化的 C++ 代码。如果他们对字符串连接这样做,他们也可能对正则表达式这样做。AFAIK,C# Regex 和 String 类留在托管世界中,这带来了一些包袱。