一、windows安装:
这个参考我另一个博客吧,省的绕弯路,我都因为这个耽误很多时间。
window下安装pybloom_live
二、pybloom_live的简单使用:
pybloom_live下面有俩个方法,BloomFilter(定容)和ScalableBloomFilter(可伸缩的)。
bloom是根据一个位进行投影的去重算法,具体我没有了解这么深,如果感兴趣,自己谷歌或者百度搜索了解吧。
1、定容BloomFilter的用法:
1 | from pybloom_live import BloomFilter |
2 | |
3 | bf = BloomFilter(capacity=1000) |
4 | |
5 | bf.add("皮卡丘1") |
6 | |
7 | print("皮卡丘1" in bf) # True |
8 | print("皮卡丘2" in bf) # False |
其中:
capacity是必须的参数,
进入方法说明,查看:
capacity意思就是做多可以加入这么多数,如果再插入就会增加错误率,但是我 好奇测试了,结果报错了。
error_rate:错误率(选填)
测试能否超过定容数量:
1 | from pybloom_live import BloomFilter |
2 | |
3 | f = BloomFilter(capacity=1000, error_rate=0.001) |
4 | print(f.capacity) |
5 | # 1000 |
6 | print('len(f):', len(f)) |
7 | for i in range(0, f.capacity): |
8 | f.add(i) |
9 | print("加入成功",i) |
10 | for i in range(0, f.capacity): |
11 | f.add(i + 999) |
12 | print("加入成功",i,len(f)) |
13 | |
14 | print('len(f):', len(f)) |
报错:
可以看出,数量是固定的,不能过多的加入。定容1000时,1001可以加入,到1002时就报错了。
2、ScalableBloomFilter(可伸缩)
这个就是如果超过初始数量,也是可以的,但是错误率会增加一点,但是不会报错。所以实际是还是使用可伸缩比较好,具体还是看看需求吧,如果数量去重的不多,定容的也很好。
1 | from pybloom_live import ScalableBloomFilter |
2 | |
3 | #mode=ScalableBloomFilter.SMALL_SET_GROWTH |
4 | sbf = ScalableBloomFilter(initial_capacity=100, error_rate=0.001, mode=ScalableBloomFilter.LARGE_SET_GROWTH) |
5 | |
6 | url = "皮卡丘1" |
7 | url2 = "皮卡丘2" |
8 | |
9 | sbf.add(url) |
10 | |
11 | print(url in sbf) # True |
12 | print(url2 in sbf) # False |
官方参数:
initial_capacity:这个初始化默认容量100,其实加入1000,也能用。错误率和mode都有默认。
3、对比定容不一样,加入的一样的ScalableBloomFilter(LARGE_SET_GROWTH)
(mode=ScalableBloomFilter.LARGE_SET_GROWTH)
我这里以分别定容为100,1000,10000,加入都是1000,测试总共加入完毕用时,和加入成功的数量为对比依据。
代码:
1 | # mode=LARGE_SET_GROWTH |
2 | # 1、定容100,加入10000 |
3 | from pybloom_live import ScalableBloomFilter |
4 | import time |
5 | # sbf = ScalableBloomFilter(initial_capacity=100, mode=ScalableBloomFilter.SMALL_SET_GROWTH) |
6 | sbf = ScalableBloomFilter(initial_capacity=100, mode=ScalableBloomFilter.LARGE_SET_GROWTH) |
7 | count = 10000 |
8 | start_time = time.time() |
9 | for i in range(0, count): |
10 | sbf.add(i) |
11 | # print("加入成功", i, len(sbf)) |
12 | end_time = time.time() |
13 | print('定容100,加入10000') |
14 | print("时间", end_time-start_time) |
15 | print("成功加入长度", len(sbf)) |
16 | |
17 | |
18 | # 2、定容1000,加入10000 |
19 | from pybloom_live import ScalableBloomFilter |
20 | import time |
21 | # sbf = ScalableBloomFilter(initial_capacity=1000, mode=ScalableBloomFilter.SMALL_SET_GROWTH) |
22 | sbf = ScalableBloomFilter(initial_capacity=1000, mode=ScalableBloomFilter.LARGE_SET_GROWTH) |
23 | count = 10000 |
24 | start_time = time.time() |
25 | for i in range(0, count): |
26 | sbf.add(i) |
27 | # print("加入成功", i, len(sbf)) |
28 | end_time = time.time() |
29 | print('定容1000,加入10000') |
30 | print("时间", end_time-start_time) |
31 | print("成功加入长度", len(sbf)) |
32 | # print((1.0 - (len(sbf) / float(count))) <= sbf.error_rate + 2e-18)#True |
33 | |
34 | |
35 | # 3、定容10000,加入10000 |
36 | from pybloom_live import ScalableBloomFilter |
37 | import time |
38 | # sbf = ScalableBloomFilter(initial_capacity=10000, mode=ScalableBloomFilter.SMALL_SET_GROWTH) |
39 | sbf = ScalableBloomFilter(initial_capacity=10000, mode=ScalableBloomFilter.LARGE_SET_GROWTH) |
40 | count = 10000 |
41 | start_time = time.time() |
42 | for i in range(0, count): |
43 | sbf.add(i) |
44 | # print("加入成功", i, len(sbf)) |
45 | end_time = time.time() |
46 | print('定容10000,加入10000') |
47 | print("时间", end_time-start_time) |
48 | print("成功加入长度", len(sbf)) |
49 | # print((1.0 - (len(sbf) / float(count))) <= sbf.error_rate + 2e-18)#True |
输出结果:
1 | |
2 | 定容100,加入10000 |
3 | 时间 0.1988668441772461 |
4 | 成功加入长度 9982 |
5 | 定容1000,加入10000 |
6 | 时间 0.15590405464172363 |
7 | 成功加入长度 9986 |
8 | 定容10000,加入10000 |
9 | 时间 0.1089334487915039 |
10 | 成功加入长度 9999 |
小总结(mode=ScalableBloomFilter.LARGE_SET_GROWTH):
通过输出的对比结果来看,选取的定容数量越是接近或者大于等于需要加入的去重数量,使用的时间越短,正确率越高。
4、对比定容不一样,加入的一样的ScalableBloomFilter(SMALL_SET_GROWTH)
(mode=ScalableBloomFilter.SMALL_SET_GROWTH)
代码:
1 | # SMALL_SET_GROWTH |
2 | # 1、定容100,加入10000 |
3 | from pybloom_live import ScalableBloomFilter |
4 | import time |
5 | sbf = ScalableBloomFilter(initial_capacity=100, mode=ScalableBloomFilter.SMALL_SET_GROWTH) |
6 | # sbf = ScalableBloomFilter(initial_capacity=100, mode=ScalableBloomFilter.LARGE_SET_GROWTH) |
7 | count = 10000 |
8 | start_time = time.time() |
9 | for i in range(0, count): |
10 | sbf.add(i) |
11 | # print("加入成功", i, len(sbf)) |
12 | end_time = time.time() |
13 | print('定容100,加入10000') |
14 | print("时间", end_time-start_time) |
15 | print("成功加入长度", len(sbf)) |
16 | |
17 | |
18 | # 2、定容1000,加入10000 |
19 | from pybloom_live import ScalableBloomFilter |
20 | import time |
21 | sbf = ScalableBloomFilter(initial_capacity=1000, mode=ScalableBloomFilter.SMALL_SET_GROWTH) |
22 | # sbf = ScalableBloomFilter(initial_capacity=1000, mode=ScalableBloomFilter.LARGE_SET_GROWTH) |
23 | count = 10000 |
24 | start_time = time.time() |
25 | for i in range(0, count): |
26 | sbf.add(i) |
27 | # print("加入成功", i, len(sbf)) |
28 | end_time = time.time() |
29 | print('定容1000,加入10000') |
30 | print("时间", end_time-start_time) |
31 | print("成功加入长度", len(sbf)) |
32 | # print((1.0 - (len(sbf) / float(count))) <= sbf.error_rate + 2e-18)#True |
33 | |
34 | |
35 | # 3、定容10000,加入10000 |
36 | from pybloom_live import ScalableBloomFilter |
37 | import time |
38 | sbf = ScalableBloomFilter(initial_capacity=10000, mode=ScalableBloomFilter.SMALL_SET_GROWTH) |
39 | # sbf = ScalableBloomFilter(initial_capacity=10000, mode=ScalableBloomFilter.LARGE_SET_GROWTH) |
40 | count = 10000 |
41 | start_time = time.time() |
42 | for i in range(0, count): |
43 | sbf.add(i) |
44 | # print("加入成功", i, len(sbf)) |
45 | end_time = time.time() |
46 | print('定容10000,加入10000') |
47 | print("时间", end_time-start_time) |
48 | print("成功加入长度", len(sbf)) |
49 | # print((1.0 - (len(sbf) / float(count))) <= sbf.error_rate + 2e-18)#True |
结果:
1 | 定容100,加入10000 |
2 | 时间 0.2538635730743408 |
3 | 成功加入长度 9961 |
4 | 定容1000,加入10000 |
5 | 时间 0.1958630084991455 |
6 | 成功加入长度 9979 |
7 | 定容10000,加入10000 |
8 | 时间 0.1329190731048584 |
9 | 成功加入长度 9999 |
小总结:(mode=ScalableBloomFilter.SMALL_SET_GROWTH)
通过上面的结果对比来看,当定容数量和结果大于等于需要去重的个数时,去重效率越好,错误率越低(加入的正确率越高)
5、俩个mode对比:
通过上面3,4的来个结果对比,一下俩个mode的区别:
mode=ScalableBloomFilter.LARGE_SET_GROWTH的结果
1 | |
2 | 定容100,加入10000 |
3 | 时间 0.1988668441772461 |
4 | 成功加入长度 9982 |
5 | 定容1000,加入10000 |
6 | 时间 0.15590405464172363 |
7 | 成功加入长度 9986 |
8 | 定容10000,加入10000 |
9 | 时间 0.1089334487915039 |
10 | 成功加入长度 9999 |
mode=ScalableBloomFilter.SMALL_SET_GROWTH的结果
1 | 定容100,加入10000 |
2 | 时间 0.2538635730743408 |
3 | 成功加入长度 9961 |
4 | 定容1000,加入10000 |
5 | 时间 0.1958630084991455 |
6 | 成功加入长度 9979 |
7 | 定容10000,加入10000 |
8 | 时间 0.1329190731048584 |
9 | 成功加入长度 9999 |
通过定容数量从小往大排序来看,当数量越接近加入的去重数量,效果幅度,SMALL_SET_GROWTH是最大的,而且SMALL_SET_GROWTH的用时和效率也比LARGE_SET_GROWTH的低,这也就反映出为什么默认是LARGE_SET_GROWTH。
6、总结测试:
通过上面的简单测试,发现使用ScalableBloomFilter(可伸缩)进入检查去重效果比较好,而且数量初始化参数尽量大于需求去重的数量效果最优,模式就使用默认的LARGE_SET_GROWTH最好。