通過重寫 Equals 方法可以改善結構體相等比較的效能方法。 如果結構體包含引用型別欄位(而不是僅僅只有值型別,如 int)。
預設情況下,結構體的相等性是通過對記憶體中的兩個結構體物件進行逐位元組比較來實現並自動確定的,但只有在結構體不包含任何引用型別的情況下。
當結構體包含引用型別欄位時, 會使用反射來比較兩個結構體物件之間的欄位,這種基於反射的方法會導致效能降低。
下圖顯示了一個僅包含值型別的結構體和另一個包含引用型別的結構體的預設相等性比較的相對效能。
【備註】圖表基於執行 10000000 次相等性的效能測試,比較時間以毫秒為單位。這裡省略了特定的數字, 以便於將注意力集中在相對差異上。
用於比較的結構體:
struct StructWithRefTypesNoOverriddenEquals
{
public int Age { get; set; }
public int Height { get; set; }
public string Name { get; set; }
}
struct StructWithNoRefTypesNoOverriddenEquals
{
public int Age { get; set; }
public int Height { get; set; }
}
重寫 Equals() 來改善效能
如果重寫 Equals 方法來提供自定義的相等性含義,則會使用重寫方法而不是預設(較慢)基於反射的機制:
struct StructWithRefTypesAndOverriddenEquals
{
public int Age { get; set; }
public int Height { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
if (!(obj is StructWithRefTypesAndOverriddenEquals))
return false;
var other = (StructWithRefTypesAndOverriddenEquals)obj;
return Age == other.Age &&
Height == other.Height &&
Name == other.Name;
}
// GetHashCode override and == != operators omitted
}
現在,將 StructWithRefTypesNoOverriddenEquals 的效能與 StructWithRefTypesandOverridEquals 的效能進行比較,生成以下結果:
實現重寫的 Equals 意味著不會使用反射,而是執行自定義的 .Equals() 程式碼來取代原來的方式。
【提示】與效能相關的所有內容都一樣,這些效能差異可能與您正在編寫的應用程式相關,也可能與您所編寫的應用程式無關。
章節:Improving Struct Equality Performance
譯書名:《C# 奇淫巧技 — 編寫更優雅的 C#》
原書名:《C# Tips — Write Better C#》
網址:https://leanpub.com/cstips