簡體   English   中英

C# Hashset.Contains 與自定義 EqualityComparer 從不調用 GetHashCode()

[英]C# Hashset.Contains with custom EqualityComparer never calls GetHashCode()

我的數據庫中有一個非常大(數十萬)的客戶對象哈希集。 然后我得到一個新導入的客戶對象哈希集,並且必須檢查每個新的 object,如果它包含在現有的哈希集中。 性能非常重要。

我不能使用默認的 Equalitycomparer,因為它只需要基於三個屬性進行比較。 此外,由於其他原因,我無法覆蓋客戶 class 的 Equals 和 GetHashCode 函數。 因此,我的目標是自定義 EqualityComparer(我嘗試實現 IEqualityComparer 或從 EqualityComparer 繼承並像您在下面看到的那樣覆蓋 - 兩者都具有相同的最終結果)。

public class CustomerComparer : EqualityComparer<Customer>
    {
        public CustomerComparer(){ }

        public override bool Equals(Customer x, Customer y)
        {
            return x != null &&
                   y != null &&
                   x.Name == y.Name &&
                   x.Description == y.Description &&
                   x.AdditionalInfo == y.AdditionalInfo
        }

        public override int GetHashCode(Customer obj)
        {
            var hashCode = -1885141022;
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(obj.Name);
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(obj.Description);
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(obj.AdditionalInfo);
            return hashCode;
        }
    }

現在我的問題是:當我使用默認的 EqualityComparer 時,通常只調用 Customer 的 GetHashCode 方法,並且我的用例的性能非常好(1-2 秒)。 當我使用我的自定義 EqualityComparer 時,永遠不會調用 GetHashCode 方法,但總是調用 Equals 方法。 我的用例的性能很糟糕(幾個小時)。 請參見下面的代碼:

public void FilterImportedCustomers(ISet<Customer> dataBase, IEnumerable<Customer> imported){

    var equalityComparer = new CustomerComparer();
    foreach (var obj in imported){
        
        //great performance, always calls Customer.GetHashCode
        if (!dataBase.Contains(obj){
        //...
        }

        //awful performance, only calls CustomerComparer.AreEqual
        if (!dataBase.Contains(obj, equalityComparer))
        //...
        }            
    }
}

有誰知道,我該如何解決這個問題? 那將是驚人的,我真的被困在試圖解決這個巨大的性能問題。

編輯:

我在初始化哈希集時通過傳遞我的 EuqalityComparer 解決了這個問題! 通過使用采用 IEqualityComparer 的構造函數重載,因此 var database = new HashSet(new CustomerComparer())

感謝你們!

我通過在初始化哈希集時傳遞我的 EqualityComparer 來解決它! 使用采用 IEqualityComparer 的構造函數重載,因此 var database = new HashSet(new CustomerComparer())

感謝 Lee 和 NetMage 在我原來的帖子下發表評論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM