Xor過濾器:比布隆Bloom過濾器更快,更小

banq發表於2019-12-20

在軟體中,您經常需要檢查集合中是否包含某些物件。例如,您可能有一個禁止的Web地址列表。當有人輸入新的網址時,您可能要檢查它是否屬於您的黑名單。或者,也許您有大量已使用的密碼,並且想要檢查建議的新密碼是否屬於此洩露密碼列表的一部分。

解決此問題的標準方法是建立一些鍵值資料結構。如果您有足夠的記憶體,則可以建立一個雜湊表。或者您可能是一個很好的舊資料庫。

但是,此類方法可能會使用過多的記憶體或速度太慢。因此,您想使用可以快速過濾請求的小型資料結構。例如,如果您有一個很小的資料結構可以可靠地告訴您您的密碼肯定不在洩露的密碼列表中,該怎麼辦?

實現這種過濾器的一種方法是計算所有物件的雜湊值。雜湊值是您從物件生成的隨機數,即相同的物件始終生成相同的隨機數,而其他物件很可能生成其他數。因此,密碼“Toronto”可能會對映到雜湊值32。然後,您可以將這些小數字儲存到鍵值儲存中,例如雜湊表。因此,您不需要儲存所有物件。例如,您可以為每個可能的密碼儲存32位數字。如果您給我一個潛在的密碼,我會檢查其對應的32位值是否在列表中,如果不是,則告訴您它是安全的。因此,如果您給我“ Toronto”,我會檢查表中是否有32。否則,我會將您的請求傳送到更大的資料庫,進行全面查詢。我徒勞地傳送給您以進行全面查詢的概率稱為“誤報概率”。

儘管此雜湊表方法可能很實用,但最終每個值可能使用4個位元組。也許這太多了?Bloom過濾器可以解救。布隆過濾器的工作原理類似,不同之處在於您可以從物件中計算多個雜湊值。您可以將這些雜湊值用作位陣列中的索引。將物件新增到集合中時,將與物件對應的所有位都設定為1。當您收到一個新物件並想要檢查它是否屬於該集合時,您只需檢查是否所有位都已被設定。實際上,每個值將使用少於4個位元組,並且仍然能夠實現小於1%的下降正率。

儘管布隆過濾器是一種教科書演算法,但它也有一些明顯的缺點。一個主要的問題是它需要許多資料訪問和許多雜湊值來檢查物件是否是集合的一部分。簡而言之,它並不是最理想的。

你能做得更好嗎?是。除其他選擇外,Fan等推出了布穀鳥Cuckoo過濾器,該過濾器比布隆過濾器佔用的空間小,速度快。儘管實現Bloom過濾器是一個相對簡單的練習,但是Cuckoo過濾器需要更多的工程設計。

在將程式碼限制為您可以掌握的東西的同時,我們還能做得更好嗎?

事實證明,您可以使用Xor過濾器。我們剛剛發表了一篇名為“ Xor過濾器:比Bloom和Cuckoo過濾器更快,更小”的論文,該論文將發表在《實驗演算法學報》上。

Go中的完整實現少於300行.

我們還有一個優化的C版本,因為它是一個單標頭檔案,所以可以輕鬆地整合到您的專案中。它大於300行,但是包含不同的替代方法,包括構建速度稍快的方法。我用C語言編寫了一個小型示例,其中涉及了密碼檢測問題。xor過濾器的構建時間要長一點,但是一旦構建,它會使用更少的記憶體,並且在某些演示測試中大約快25%。

我們也有JavaC ++實現

 

相關文章