这是对代码路径的一些微基准测试,该代码路径每纳秒要经过数百万亿次遍历,并且需要快速进行。
对于下面的代码段,比较
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
路径)N.B. :我刚刚发现,使用
Ordinal
而不是InvariantCulture
调用EndsWith时,EndsWith比Regex快得多……不幸的是,没有RegexOptions.Ordinal
可以与之比较。我还期望编译后的正则表达式很快,但是如何击败专用方法呢?
乐码:
string[] BunchOfIDs =
{
"zxc@x@432143214@O@abcße",
"zxc@x@432143214@T@abcßX",
"qwe@x@432143214@O@abcße",
"qwe@x@432143214@XXabc",
"zxc@x@1234@O@aXcße",
"qwe@y@1234@O@aYcße",
};
var endsWith = "@abcße";
var endsWithRegex = new Regex("@abcße$", RegexOptions.None);
int reps = 20000000;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("=============================");
int x = 0;
var sw = Stopwatch.StartNew();
for (int j = 0; j < reps; j++)
{
x += BunchOfIDs[j % BunchOfIDs.Length].EndsWith(endsWith, StringComparison.InvariantCulture) ? 1 : 2;
}
Console.WriteLine("EndsWith: " + sw.Elapsed + ". Ignore this: " + x);
x = 0;
sw = Stopwatch.StartNew();
for (int j = 0; j < reps; j++)
{
x += endsWithRegex.IsMatch(BunchOfIDs[j % BunchOfIDs.Length]) ? 1 : 2;
}
Console.WriteLine("Regex : " + sw.Elapsed + ". Ignore this: " + x);
}
最佳答案
有可能
因为 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?
关于.net - 为什么regex.IsMatch(str)比str.EndsWith(不变文化)快?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27958053/