为什么regex.IsMatch(str)比str.EndsWith(不变文化)更快?

时间:2015-01-15 06:44:49

标签: .net regex string performance

这是针对代码路径的一些微基准测试,每个纳秒需要遍历数十亿次并且需要快速。

对于下面的代码段,比较

  • x.EndsWith(y, InvariantCulture)
  • Regex(y, Compiled | CultureInvariant).IsMatch(x)

我得到以下数字:

=============================
Regex   : 00:00:01.2235890. Ignore this: 16666666
EndsWith: 00:00:03.2194626. Ignore this: 16666666
=============================
Regex   : 00:00:01.0979105. Ignore this: 16666666
EndsWith: 00:00:03.2346031. Ignore this: 16666666
=============================
Regex   : 00:00:01.0687845. Ignore this: 16666666
EndsWith: 00:00:03.3199213. Ignore this: 16666666

换句话说,EndsWith需要的时间是Regex的3倍。

我应该注意,我尝试使用其他值和取决于使用的字符串值,有时EndsWith更快,有时Regex

EndsWith(x, InvariantCulture)归结为一些参数检查,然后 extern int nativeCompareOrdinalEx(String, int, String, int, int),我期望它快速。 (正如@nhahtdh正确指出的那样,在InvariantCulture的情况下,它会调用CultureInfo.InvariantCulture.CompareInfo.IsSuffix which calls InternalFindNLSStringEx。我不小心跟踪了Ordinal路径

NB :我刚刚发现,当使用Ordinal而不是InvariantCulture调用EndsWith时,EndsWith比Regex快得多......不幸的是没有{{1与...进行比较。

我还期望编译的正则表达式很快,但它怎么能超越专门的方法?

Le code:

RegexOptions.Ordinal

1 个答案:

答案 0 :(得分:5)

可能是

因为 StringComparison.InvariantCulture != RegexOptions.CultureInvariant

此代码段

var str = "ss";
var endsWith = "ß";
var endsWithRegex = new Regex("ß$",
    RegexOptions.Compiled | RegexOptions.CultureInvariant);
Console.WriteLine(str.EndsWith(endsWith, StringComparison.InvariantCulture)
    + " vs "
    + endsWithRegex.IsMatch(str));

打印

True vs False

因此,看起来RegexOptions.CultureInvariant并不意味着StringComparison.InvariantCulture隐含的内容。 RegexOptions.CultureInvariant可能更像是StringComparison.Ordinal吗?