3

给定这样的字符串:

string s1 = "Abc";
string s2 = "ABC";

什么更快:

Regex.Match(s1, s2, RegexOptions.IgnoreCase)

或者

s1.ToLower() == s2.ToLower()

如果它们相同或一个比另一个更快,那么什么时候使用一个比另一个更好?

4

7 回答 7

8

可能第二个更快,但我会避免这两种方法。

更好的是使用string.Equals带有适当StringComparison参数的方法:

s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase)

在线查看它:ideone

于 2012-05-13T16:02:11.013 回答
4

从理论上讲,比较两个字符串应该更快,RegEx 被认为是相当慢的。

但是,如果您想在忽略大小写的情况下将字符串 s1 与 RegEx s2 匹配(这与比较 2 个字符串不同),那么第一个解决方案会更好,因为它应该避免创建另一个字符串。

与此类问题一样,我会运行基准测试并比较两种性能:)

于 2012-05-13T16:04:43.640 回答
4

@Mark Byers 已经发布了正确答案。

我想强调的是,你永远不应该使用 ToLower 进行字符串比较。这是不正确的。

s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase) //#1
s1.ToLower() == s2.ToLower() //#2
s1.ToLowerInvariant() == s2.ToLowerInvariant() //#3

(2) 和 (3) 对于外来语言和奇怪字符都是不正确的。土耳其语的“I”是典型的例子。

始终使用 #1,即使在哈希表中

(非常特殊的情况除外)

于 2012-05-13T16:12:27.537 回答
3

应该注意的Regex.Match(s1, s2, RegexOptions.IgnoreCase)是,在一般情况下检查不区分大小写的相等性并不是一种安全的方法。s2考虑is的情况".*"Regex.Match无论是什么,都将永远返回真s1

于 2012-05-13T16:14:11.620 回答
3

这可能是 我见过的最极端的过早优化案例。相信我,您永远不会遇到与此问题相关的情况。

不要听那些告诉你避免使用正则表达式的人,因为“它们很慢”。 写得不好的正则表达式确实会占用一些可怕的资源,但这是编写正则表达式的人的错。精心设计的正则表达式对于人们应用它们的绝大多数任务来说足够快。

于 2012-05-13T22:12:46.483 回答
0

比较会更快,但与其转换为小写或大写然后进行比较,不如使用可以不区分大小写的相等比较。例如:

        s1.Equals(s2, StringComparison.OrdinalIgnoreCase)
于 2012-05-13T17:41:03.450 回答
0

以下是所提出的 3 种方法的小比较:

正则表达式:282ms ToLower: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);
}
于 2012-05-13T21:55:32.043 回答