利用哈希的其中一個思想,相同的物件的哈希值相同,可以用來提升一些大物件集合的進行物件相等判斷的性能,大物件的相等判斷指的是有某些型別的相等判斷需要用到物件的很多屬性或欄位進行參與判斷邏輯才能判斷兩個物件是否相等,當這些大物件存放在集合里面,此時進行大量的相等判斷將會因為需要有大量的屬性或欄位的判斷而降低性能,本文告訴大家如何使用此哈希的思想提升判斷的性能
故事的背景是我在做一個比 Office 的 Word 差得多的軟體,此軟體有文本的功能,允許每個文字都有自己的文本屬性,有趣的是,我期望將文本的文本屬性進行合并,總不能一篇一萬字的博客有一萬個文本屬性吧,但文本屬性是一個比較大的型別,里面包含了一堆屬性,如字體字號等等
在拿到輸入的一堆文本屬性的集合里面,需要進行文本屬性物件之間的相等判斷用于合并多余的文本屬性,在使用 dotTrace 進行性能測量時,了解到有大量的資源都用在了相等判斷里面,因為一個文本屬性和另一個文本屬性的相等比較大約需要比較近 100 個屬性,不要聽著 100 個屬性很驚訝,在 Word 里面可是按照 MB 計算的屬性量哦
在進行性能優化的時候,我考慮用上哈希的思想,思想就是將大物件的相等比較分為兩步,第一步判斷大物件的哈希值是否相等,基于相等的物件的哈希值相等的思想,可以了解到想要兩個物件相等,第一步判斷哈希值必須相等,在判斷哈希之后再進行大物件原本的物件相等判斷
判斷哈希值相當于只是判斷一個 int 值而已,占用資源基本可以被忽略,因此可以在存在比較多不相同的物件的時候,可以提升對不相同物件的判斷的性能從而提升集合的判斷相等的性能
以下是更詳細的細節
在制作物件的哈希值的時候,期望是將所有參與相等判斷的屬性和欄位都加入到哈希值的創建中,這樣創建出來的哈希值將會包含所有參與判斷的欄位和屬性的資訊,但同時也會帶來一個問題是哈希值的計算也是需要計算資源的,可以考慮將哈希值進行快取
在 dotnet 里面,默認物件的 GetHashCode 是不推薦將非只讀的屬性和欄位加入到此方法的哈希值制作,但是在本文的需求下,是無視此條例,需要將所有參與判斷相等的屬性和欄位都加入哈希值的制作,因此建議本文的方法不要放入到物件的 GetHashCode 方法里面,而是自己再創建一個新方法或者放在某個輔助類
在制作大物件的哈希值時,需要充分考慮業務上的需要,寧可哈希沖突大一些也不要誤判,也就是說寧可兩個不相等的物件回傳相同的哈希值,也不要有存在某些相等的物件可能回傳不同的哈希值,其細節在于,在大物件里面,參考的一些屬性對應的型別所獲取的哈希值如果不能準確獲取,如是一個介面等,那么建議將此屬性或欄位不加入到哈希值的制作,相當于判斷哈希值是例外了此屬性或欄位的判斷,其原因是介面相對來說是自由的,如果有某些業務詭異實作了此介面,讓原本兩個相等的物件回傳了不相等的哈希值,那么將會讓本文的邏輯炸掉
博客園博客只做備份,博客發布就不再更新,如果想看最新博客,請到 https://blog.lindexi.com/

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可,歡迎轉載、使用、重新發布,但務必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布,如有任何疑問,請與我[聯系](mailto:[email protected]),
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/317414.html
標籤:.NET Core
