理论部分来自于一个接地气文章(除了讲了很好的故事外,还介绍了 Google 的 guava 是咋实现布隆过滤器的)http://www.cnblogs.com/crossoverJie/p/10018231.htmlhtml
下面的测试在个人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)); }
https://www.itcodemonkey.com/article/8258.html
这里面用的是 bitmap,即位图法。
我的感受这种方法只适合判断整数元素是否存在。 优点是判断准确,且速度极快。
而布隆过滤器不只适合判断整数元素,也适合判断字符串元素,例如网址。 劣势是数据量为千万级时,判断速度6秒,很慢了已经。code
我的认为:分布式部署是布隆过滤器和bitmap加速的最无脑但颇有效的方式,尤为针对布隆过滤器的加速,是个很好的选择!!!htm