簡體   English   中英

C#中的字符串比較性能

[英]String comparison performance in C#

有許多方法可以比較字符串。 通過一種方式比另一種方式獲得性能提升嗎?

我總是選擇像這樣比較字符串:

string name = "Bob Wazowski";
if (name.CompareTo("Jill Yearsley") == 0) {
    // whatever...
}

但我發現很少有人這樣做,如果有的話,我看到更多的人只是做一個直接的==比較,據我所知,這是比較字符串的最差方式。 我錯了嗎?

另外,它是如何比較LINQ查詢中的字符串的? 例如,我喜歡做以下事情:

var results = from names in ctx.Names
              where names.FirstName.CompareTo("Bob Wazowski") == 0
              select names;

但同樣,我看到很少有人在他們的LINQ查詢中進行字符串比較。

根據Reflector

"Hello" == "World"

是相同的

String.Equals("Hello", "World");

它基本上確定它們是否是同一個引用對象,如果它們中的任何一個為null,如果一個為null而另一個為null則為自動false,然后比較不安全循環中的每個字符。 所以它根本不關心文化規則,這通常不是什么大問題。

"Hello".CompareTo("World") == 0

是相同的

CultureInfo.CurrentCulture.CompareInfo.Compare("Hello", "World", CompareOptions.None);

就功能而言,這基本上是相反的。 它考慮了文化,編碼以及字符串在上下文中的所有其他內容。

所以我想象String.CompareTo比相等運算符慢幾個數量級

對於LINQ而言,如果使用LINQ-to-SQL並不重要,因為兩者都會生成相同的SQL

var results = from names in ctx.Names
          where names.FirstName.CompareTo("Bob Wazowski") == 0
          select names;

SELECT [name fields]
FROM [Names] AS [t0]
WHERE [t0].FirstName = @p0

所以你真的沒有為LINQ-to-SQL獲得任何東西,除了更難閱讀代碼和可能更多的表達式解析。 如果你只是使用LINQ作為標准數組的東西,那么我上面列出的規則適用。

在我看來,你應該總是使用最清晰的方式,即使用==

這可以直接理解:當“你好”等於“世界”然后做一些事情。

if ("Hello" == "World")
    // ...

在內部,調用String::Equals ,它明確地存在於此目的 - 比較兩個字符串是否相等。 (這與指針和引用等無關)

這里不是立即清楚 - 為什么比較為零?

if ("Hello".CompareTo("World") == 0)

.CompareTo不僅僅用於檢查相等性(你有==) - 它比較兩個字符串。 您可以使用.CompareTo來確定一個字符串比另一個字符串“更大”。 可以檢查是否相等,因為它對於相等的字符串產生零,但這不是它的概念。

因此,有不同的方法和接口用於檢查相等性(IEquatable,operator ==)和比較(IComparable)

Linq與普通C#的行為不同。

閱讀傑夫的最佳代碼完全沒有代碼 foo.CompareTo(bar) == 0 :可怕的視覺混亂。 占用大量空間並沒有傳達任何有趣的意義。 事實上,它強調了很多無關緊要的東西,這些東西會把注意力從真正的問題上轉移開來。

如果使用這個較長的變體沒有明確的原因,請不要。

至於性能:對於這個簡單的情況,它無關緊要。 如果相等運算符==應該比CompareTo表現更差,請隨時向Microsoft提交錯誤報告。 這絕不可能發生。

MSDN聲明你應該根據你需要執行的任務使用比較函數:

CompareTo方法主要用於排序或字母順序操作。 當方法調用的主要目的是確定兩個字符串是否相等時,不應使用它。 要確定兩個字符串是否相等,請調用Equals方法。

因此,如果它不是關於排序和retrun值不重要我會說應該使用:

first.Equals(second)或者比較是文化特定的,例如在德語等語言中:

String.Equals(first, second, StringComparison.CurrentCulture)

看看這些鏈接:

如何:比較字符串(C#編程指南)

String.CompareTo方法(對象)

最近關於修剪弦樂的最快方法有一個非常類似的問題,但它基本上是對比較它們的不同方式的基准。

你可以查看這篇文章的基准。

有一篇很好的文章比較.NET中的平等值:身份和等價 ,這比僅僅字符串比較更為通用,但仍然非常有趣。

如果相等運算符實際上比CompareTo表現差 - 那么Microsoft不會讓相等運算符的實現調用CompareTo嗎?

只需使用相等運算符來測試相等性。

是我發現的最完整,最有幫助的MSDN指南,用於字符串比較。

使用與StringComparison.Ordinal或StringComparison.OrdinalIgnoreCase的比較可獲得更好的性能。

我通常使用帶有StringComparison參數的重載的String.Compare,因為那時我可以絕對明確比較是否是區分大小寫和文化敏感的。 這需要.NET 2.0或更高版本。

對於非文化敏感的比較,最快的是StringComparison.Ordinal(或StringComparison.OrdinalIgnoreCase,如果不區分大小寫)。

使用==的問題在於,作者已經考慮了案例和文化敏感性並不清楚。

有關於這個問題的一個很好的MSDN文章在這里

要在C#中比較string的最佳方法是使用a.Equals(b) ,其中ab是字符串。 這是比較字符串的最佳方法,因為它比較了對象ab的值,並且不依賴於對象的引用。

如果您要使用==符號,如果兩個對象具有相同的引用,則結果將相等,但如果它們具有不同的引用並且具有相同的值,則會出現問題。

如果您測試另一個字符串是否在另一個字符串的相同位置之前,之后或出現在另一個字符串的相同位置,其中它將分別返回負值,正值或零值,則compareTo方法是最佳使用方法。 如果參數為null它也將返回正值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM