iT邦幫忙

DAY 10
1

.NET程式效能Issue系列 第 10

[Day 10][C#]Effective C# 條款十: 理解GetHashCode()方法的缺陷

  • 分享至 

  • xImage
  •  

GetHashCode對於參考類型來說,可以正常運作,但其效率很低。而對於值類型來說,其實現通常是不正確的。

GetHashCode若要重新定義,我們必須要遵循下列原則:

1,兩個相等的物件必須具有相同的雜湊碼。

2.對於任何一個物件,不論叫用甚麼方法,其GetHashCode永遠都必須返回相同的值。

3.對於所有輸入,雜湊函式應在所有整數中產生一隨機分佈。這樣,我們才能從一個雜湊容器獲得效率的提升。

參考類型的GetHashCode
先來看一下第一條規則。在程式未重新定義Operator==時,如果兩個物件相等,那麼Object.GetHashCode會返回同樣的雜湊值。若程式有重新定義Operator==,則我們必須跟著重新定義Object.GetHashCode方法。

而第二條規則,Object.GetHashCode預設就是永遠不會改變的。

至於第三個規則,Object.GetHashCode未能滿足此規則。除非建立了數量非常多的物件,否則其返回的雜湊值會集中在整數範圍的底端。

因此,Object.GetHashCode在功能面是正常的,但其效率不高。所以當要建立一參考型別時,我們應重新定義其GetHashCode方法,使雜湊值能在整數範圍內有良好的分佈。

值類型的GetHashCode
System.ValueType重新定義了GetHashCode方法,為值類型提供預設的實現。預設的實現會返回值類型中所定義的第一個成員的雜湊碼。

一樣的,讓我們來看一下GetHashCode重新定義要遵循的三個原則。

第一個規則對於值類型來說,絕大多數的情況下是滿足的。但我們也可能打破此規則,像是重新定義了Operator==,且未把值類型的第一個成員加入判斷條件,該條款就不會成立。

至於第二個規則,必須結構的第一個成員是一個常數型別,該規則才會被滿足。這也是為何條款七會建議"盡可能實現具有常量性的值類別"的另一個理由。

第三個規則一樣也是要看結構中的第一個成員。當第一個結構成員會在所有整數中產生一個隨機分佈,則會滿足此條款。但若是第一個結構成員經常都是相同的值,那就違反此規則。


上一篇
[Day 9][C#]Effective C# 條款九: 理解幾個相等判斷之間的關係
下一篇
[Day 11][C#]Effective C# 條款十一: 優先採用foreach迴圈
系列文
.NET程式效能Issue11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言