[英]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)
看看這些鏈接:
最近關於修剪弦樂的最快方法有一個非常類似的問題,但它基本上是對比較它們的不同方式的基准。
你可以查看這篇文章的基准。
有一篇很好的文章比較.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)
,其中a和b是字符串。 這是比較字符串的最佳方法,因為它比較了對象a和b的值,並且不依賴於對象的引用。
如果您要使用“ ==
”符號,如果兩個對象具有相同的引用,則結果將相等,但如果它們具有不同的引用並且具有相同的值,則會出現問題。
如果您測試另一個字符串是否在另一個字符串的相同位置之前,之后或出現在另一個字符串的相同位置,其中它將分別返回負值,正值或零值,則compareTo
方法是最佳使用方法。 如果參數為null
它也將返回正值
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.