布隆過濾器,簡易實驗報告 --- 咋判斷百萬級千萬級甚至億級數據中某元素是不存在的?速度快,佔內存少

理論部分來自於一個接地氣文章(除了講了很好的故事外,還介紹了 Google 的 guava 是咋實現布隆過濾器的)http://www.cnblogs.com/crossoverJie/p/10018231.htmlhtml

1 布隆過濾器做用: 判斷大規模數據中,某元素是否存在。

  • 某元素斷定爲不存在,100%準確
  • 某元素斷定爲存在,若誤報率設定爲0.01,則99%是準確的。布隆過濾器沒法保證此項判斷100%準確。(你把下面代碼裏的0.01設定成0試試?)

2 guava 的布隆過濾器 vs. java集合框架中的 HashSet

下面的測試在個人2012年老筆記本電腦上進行的。java

布隆過濾器(誤報率設定爲0.01) VS HashSet面試

數據規模 布隆過濾器(代碼1)用時 HashSet(代碼2)用時
10 30ms 0
100 30ms 0
1000 60ms 0
1萬 100ms 10ms
10萬 180ms 40ms
100萬 700ms 950ms
1000萬 6s 難以忍受 10秒
1億 56s 沒法忍受了 崩潰

上表僅僅在耗時上作比較,耗費內存方面沒作比較。數據量很大時,布隆過濾器表現很是優秀,而 HashSet 就不好了。
查詢所需時間同數據規模和誤報率設定有直接關係。hashSet 數據規模小時是王者,隨着數據規模增大,變青銅,到最後麻爪,崩潰了!框架

上面的比較,來自於下面2段代碼。
代碼1: 應用 Goolge guava 的布隆過濾器代碼以下:分佈式

@Test
    public void guavaTest(){
        long start = System.currentTimeMillis();
        BloomFilter<Integer> filter = BloomFilter.create(
                Funnels.integerFunnel(),
                capacity,   // e.g. int capacity=100000
                0.01
        );
        for(int i=0; i<capacity; i++){
            filter.put(i);
        }
        Assert.assertTrue(filter.mightContain(1));
        long end = System.currentTimeMillis();
        System.out.println("執行時間:" + (end - start));
    }

代碼2:用 java容器 HashSet 處理此應用,代碼以下:測試

@Test
    public void hashSetTest(){
        long start = System.currentTimeMillis();
        Set<Integer> hashset = new HashSet(capacity);  // e.g. int capacity=100000
        for(int i=0; i<capacity; i++){hashset.add(i);}
        Assert.assertTrue(hashset.contains(1));
        long end = System.currentTimeMillis();
        System.out.println("執行時間:" + (end - start));
    }

3 話題拓展 【面試現場】如何判斷一個數是否在40億個整數中?

https://www.itcodemonkey.com/article/8258.html
這裏面用的是 bitmap,即位圖法。
我的感受這種方法只適合判斷整數元素是否存在。 優點是判斷準確,且速度極快。
而布隆過濾器不只適合判斷整數元素,也適合判斷字符串元素,例如網址。 劣勢是數據量爲千萬級時,判斷速度6秒,很慢了已經。code

4 加速布隆過濾器和 bitmap

我的認爲:分佈式部署是布隆過濾器和bitmap加速的最無腦但頗有效的方式,尤爲針對布隆過濾器的加速,是個很好的選擇!!!htm

相關文章
相關標籤/搜索