簡體   English   中英

C#中帶有兩個哈希函數的字典?

[英]Dictionary with two hash functions in C#?

我有一個巨大的(>> 10米)條目列表。 每個條目都提供兩個哈希函數:

  • 便宜:快速計算哈希值,但其分布很糟糕(可能將99%的項目放在1%的哈希空間中)
  • 昂貴:需要花費大量時間進行計算,但分布也要好得多

普通的字典讓我只使用其中一個哈希函數。 我想要一個首先使用廉價哈希函數的字典,並在碰撞中檢查昂貴的哈希函數。

為此,在詞典中使用字典似乎是個好主意。 我目前基本上使用這個怪物:

Dictionary<int, Dictionary<int, List<Foo>>>;

我改進了這個設計,所以只有當實際上有兩個相同的廉價哈希項時才會調用昂貴的哈希。

它完美地適合我,並為我做一個完美的工作,但它看起來應該已經死了6500萬年前。

據我所知,此功能未包含在基本框架中。 我即將寫一篇DoubleHashedDictionary類,但我想先了解你的意見。

至於我的具體情況:
第一個哈希函數=文件系統目錄中的文件數(快)第二個哈希函數=文件大小的總和(慢)

編輯:

  • 更改了標題並添加了更多信息。
  • 添加了非常重要的缺失細節

在您的情況下,您在技術上使用修改的函數(A | B),而不是雙散列函數。 但是,根據您的“巨大”條目列表的大小以及數據的特征,請考慮以下事項:

  • 具有不太好的分布的20%完整哈希表可能具有超過80%的沖突機會。 這意味着您的預期功能成本可能是:(0.8昂貴+ 0.2便宜)+(查找成本)。 因此,如果您的餐桌超過20%,則可能不值得使用(A | B)方案。

  • 提出一個完美的哈希函數是可能的,但O(n ^ 3)使它變得不切實際。

  • 如果性能非常重要,您可以通過測試關鍵數據上的各種哈希函數,為特定數據制作專門調整的哈希表。

您是否看過Power CollectionsC5 Collections庫? Power Collections庫最近沒有太多動作,但C5的東西似乎是相當最新的。

我不確定這兩個庫是否具有您需要的功能,但它們非常有用並且它們是開源的,因此它可以為您提供一個合適的基礎實現,以擴展到您所需的功能。

你基本上是在談論哈希表的哈希表,每個哈希表都使用不同的GetHashCode實現......雖然我認為你可能會認真考慮一下你是否真的會在一個或另一個上做一個性能改進...

實際上是否會有大量的對象通過快速哈希機制定位,而不必采用更昂貴的對象來進一步縮小范圍? 因為如果你不能完全從第一次計算中找到大量的數據,你就可以分兩步完成任務(不知道數據很難預測是否是這種情況)。

如果它將在一個步驟中成為一個重要的數量,那么你可能需要進行一些調整以計算出在外部的每個散列位置存儲多少記錄,然后再使用內部“昂貴”的散列表查找而不是散列數據的更多處理,但在某些情況下,我可以看到你如何從中獲得性能增益(情況會很少,而且不可思議)。

編輯

我剛剛看到你對這個問題的修正 - 你打算不管怎么做兩次查找...我懷疑你會從中獲得任何性能上的好處,你不能通過更好地配置主哈希表來獲得。 您是否嘗試使用在構造函數中傳遞適當容量的單個字典,並且可能將兩個哈希代碼的XOR作為哈希代碼?

首先,我認為你正在實現自己的散列表的正確途徑,如果你所描述的是真正需要的。但作為評論家,我想問幾個問題:

您是否考慮過為每個條目使用更獨特的東西?

我假設每個條目都是文件系統目錄信息,您是否考慮使用其完整路徑作為密鑰? 用計算機名/ IP地址加前綴?

另一方面,如果您使用多個文件作為哈希鍵,這些目錄是否永遠不會改變? 因為如果散列鍵/結果發生變化,您將永遠無法再找到它。

在這個主題上,如果目錄內容/大小永遠不會改變,你可以將該值存儲在某處以節省實際計算時間嗎?

只是我的幾美分。

暫無
暫無

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

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