[英]c# performance: type comparison vs. string comparison
哪個更快? 這個:
bool isEqual = (MyObject1 is MyObject2)
或這個:
bool isEqual = ("blah" == "blah1")
找出哪個更快會很有幫助。 顯然,如果像程序員經常做的那樣將 .ToUpper() 應用於字符串比較的每一側,那將需要重新分配內存,這會影響性能。 但是,如果 .ToUpper() 不在上面示例中的等式之外呢?
我在這里有點困惑。
正如其他答案所指出的那樣,您正在比較蘋果和橙子。 ::rimshot::
如果要確定對象是否屬於某種類型,請使用is
運算符。
如果您想比較字符串,請使用==
運算符(或其他適當的比較方法,如果您需要一些花哨的東西,例如不區分大小寫的比較)。
一種操作與另一種操作相比有多快(沒有雙關語)似乎並不重要。
仔細閱讀后,我認為您想將字符串比較的速度與引用比較的速度(System.Object 基類型中使用的比較類型)進行比較。
如果是這樣,那么答案是引用比較永遠不會比任何其他字符串比較慢。 .NET 中的引用比較與 C 中的指針比較非常相似 - 盡可能快。
但是,如果字符串變量s
的值為"I'm a string"
,但以下比較失敗,您會有什么感覺:
if (((object) s) == ((object) "I'm a string")) { ... }
如果您只是比較引用,則可能會發生這種情況,具體取決於s
的值是如何創建的。 如果它最終沒有被實習,它將與文字字符串具有不同的引用,因此比較將失敗。 所以你可能有一個更快的比較,但並不總是有效。 這似乎是一個糟糕的優化。
根據Maximizing .NET Performance一書,調用
bool isEqual = String.Equals("test", "test");
在性能上與
bool isEqual = ("test" == "test");
電話
bool isEqual = "test".Equals("test");
理論上比調用靜態 String.Equals 方法慢,但我認為您需要比較幾百萬個字符串才能實際檢測速度差異。
我給你的提示是這樣的; 不要擔心哪種字符串比較方法更慢或更快。 在正常的應用程序中,您永遠不會注意到差異。 你應該使用你認為最易讀的方式。
第一個用於比較類型而不是值。 如果要將字符串與不敏感的大小寫進行比較,可以使用:
string toto = "toto";
string tata = "tata";
bool isEqual = string.Compare(toto, tata, StringComparison.InvariantCultureIgnoreCase) == 0;
Console.WriteLine(isEqual);
如果我理解這個問題,並且您真的想將引用相等性與普通的“比較內容”進行比較:構建一個測試用例並調用object.ReferenceEquals與 a == b 進行比較。
注意:您必須了解區別是什么,並且在大多數情況下您可能無法使用參考比較。 如果您確定這是您想要的,它可能會快一點。 您必須自己嘗試並評估這是否值得麻煩。
你告訴我怎么樣? :)
從這篇 Coding Horror post 中獲取代碼,並插入您的代碼來代替他的算法進行測試。
使用“==”運算符比較字符串是將字符串的內容與字符串對象引用進行比較。 比較對象會調用對象的“Equals”方法來判斷它們是否相等。 Equals 的默認實現是進行引用比較,如果兩個對象引用是同一個物理對象,則返回 True。 這可能比字符串比較快,但取決於被比較的對象類型。
我覺得這些答案中的任何一個都沒有解決實際問題。 假設此示例中的字符串是類型的名稱,我們正在嘗試查看比較類型名稱或類型以確定它是什么是否更快。
我把它們放在一起,令我驚訝的是,在我運行的每個測試中,檢查類型名稱字符串比檢查類型快 10%。 我特意使用最簡單的字符串和類來查看是否可能更快,結果證明這是可能的。 不確定來自重度繼承類的更復雜的字符串和類型比較。 這當然是一個微操作,我想可能會在語言發展的某個時刻發生變化。
就我而言,我正在考慮一個基於此名稱切換的值轉換器,但它也可以切換類型,因為每種類型都指定了一個唯一的類型名稱。 值轉換器會根據顯示的項目類型找出要顯示的字體真棒圖標。
using System;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApp1
{
public sealed class A
{
public const string TypeName = "A";
}
public sealed class B
{
public const string TypeName = "B";
}
public sealed class C
{
public const string TypeName = "C";
}
class Program
{
static void Main(string[] args)
{
var testlist = Enumerable.Repeat(0, 100).SelectMany(x => new object[] { new A(), new B(), new C() }).ToList();
int count = 0;
void checkTypeName()
{
foreach (var item in testlist)
{
switch (item)
{
case A.TypeName:
count++;
break;
case B.TypeName:
count++;
break;
case C.TypeName:
count++;
break;
default:
break;
}
}
}
void checkType()
{
foreach (var item in testlist)
{
switch (item)
{
case A _:
count++;
break;
case B _:
count++;
break;
case C _:
count++;
break;
default:
break;
}
}
}
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 100000; i++)
{
checkTypeName();
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
sw.Restart();
for (int i = 0; i < 100000; i++)
{
checkType();
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
}
}
我假設比較第一個示例中的對象將盡可能快,因為它只是檢查兩個對象是否指向內存中的相同地址。
正如已經多次提到的那樣,也可以比較字符串上的地址,但如果兩個字符串是從不同來源分配的,則這不一定有效。
最后,在可能的情況下,嘗試根據類型比較對象通常是一種很好的形式。 它通常是最具體的識別方法。 如果您的對象需要用它們在內存中的地址以外的其他東西來表示,則可以使用其他屬性作為標識符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.