将字符串与正则表达式与 IgnoreCase 或 ToLower 字符串方法进行比较是否更快?
本文关键字:字符串 是否 比较 方法 IgnoreCase 正则表达式 ToLower | 更新日期: 2023-09-27 18:33:58
给定如下字符串:
string s1 = "Abc";
string s2 = "ABC";
什么更快:
Regex.Match(s1, s2, RegexOptions.IgnoreCase)
或
s1.ToLower() == s2.ToLower()
如果它们是相同的,或者一个比另一个更快,那么什么时候使用一个比另一个更好?
可能第二个更快,但我会避免这两种方法。
最好是将方法string.Equals
与适当的StringComparison
参数一起使用:
s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase)
在线查看它的工作:ideone
从理论上讲,比较 2 个字符串应该更快,而正则表达式已知相当慢。
但是,如果您想在忽略大小写的情况下将字符串 s1 与正则表达式 s2 匹配(这与比较 2 个字符串不同),那么第一个解决方案更好,因为它应该避免创建另一个字符串。
与此类问题一样,我会运行基准测试并比较两种性能:)
@Mark Byers已经发布了正确的答案。
我想强调的是,您永远不应该使用 ToLower 进行字符串比较。这是不正确的。
s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase) //#1
s1.ToLower() == s2.ToLower() //#2
s1.ToLowerInvariant() == s2.ToLowerInvariant() //#3
(2)和(3)在涉及异国语言和奇怪字符时都是不正确的。土耳其语"I"是经典的例子。
始终使用 #1,即使在哈希表中也是如此
(非常特殊情况除外)
应该注意的是,在一般情况下,Regex.Match(s1, s2, RegexOptions.IgnoreCase)
不是检查不区分大小写的相等性的安全方法。考虑s2
".*"
的情况。 无论s1
是什么,Regex.Match
都会永远回归真实!
这可能是我见过的最极端的过早优化案例。 相信我,您永远不会遇到与此问题相关的情况。
不要听所有那些告诉你避免正则表达式的人,因为"它们很慢"。 写得不好的正则表达式确实会占用资源,但这是编写正则表达式的人的错。 精心设计的正则表达式足够快,可以满足人们应用它们的绝大多数任务。
以下是提出的 3 种方法的一个小比较:
正则表达式:282ms 降低:67ms 等于:34ms
public static void RunSnippet()
{
string s1 = "Abc";
string s2 = "ABC";
// Preload
compareUsingRegex(s1, s2);
compareUsingToLower(s1, s2);
compareUsingEquals(s1, s2);
// Regex
Stopwatch swRegex = Stopwatch.StartNew();
for (int i = 0; i < 300000; i++)
compareUsingRegex(s1, s2);
Console.WriteLine(string.Format("Regex: {0} ms", swRegex.ElapsedMilliseconds));
// ToLower
Stopwatch swToLower = Stopwatch.StartNew();
for (int i = 0; i < 300000; i++)
compareUsingToLower(s1, s2);
Console.WriteLine(string.Format("ToLower: {0} ms", swToLower.ElapsedMilliseconds));
// ToLower
Stopwatch swEquals = Stopwatch.StartNew();
for (int i = 0; i < 300000; i++)
compareUsingEquals(s1, s2);
Console.WriteLine(string.Format("Equals: {0} ms", swEquals.ElapsedMilliseconds));
}
private static bool compareUsingRegex(string s1, string s2)
{
return Regex.IsMatch(s1, s2, RegexOptions.IgnoreCase);
}
private static bool compareUsingToLower(string s1, string s2)
{
return s1.ToLower() == s2.ToLower();
}
private static bool compareUsingEquals(string s1, string s2)
{
return s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase);
}
比较会更快,但与其转换为小写或大写然后进行比较,不如使用可以不区分大小写的相等比较。 例如:
s1.Equals(s2, StringComparison.OrdinalIgnoreCase)