一、直观的数据去重方式
通常我们采用如下算法对一组长度为n的数据d进行去重时。
S1.在数据中取出第x个数据(1≤x<n),d[x]
S2.在数据中取出第y个数据(x<y≤n),d[y]
S3.比较d[x]和d[y],若相同丢弃d[y],重复S2,S3直到y=n
S4.重复S1,S2,S3直到x=n-1
此算法时间复杂度近似T(n)=O(1/2n²),空间需求为size(d)。
假设现有一组数据d,单条长度500字节,共有108条,有一台计算机,每秒处理106次数据对比。由此可以计算,该次去重共需要的存储空间为S=108*500=5*1010=50G,所需要的时间T=1/2*(108)²*1/106=5*109秒≈158年
由此可见,对于大量的数据去重任务来说,这个算法是不可行的。
当然这个算法也可以通过提升硬件来减少存储和处理时间,如:将数据存储在磁盘,在需要的时候载入到内存,使用磁盘阵列来增加读取速度,来解决存储问题。增加CPU核数来增加比对速度来减少时间等。但这些都增加了成本
二、布隆过滤器
布隆过滤器是由Burton Howard Bloom于1970年提出,他是一种space efficient的概率模型数据结构,用于判断一个元素是否在集合中。
一个空的布隆过滤器是一个m bit的bitmap,每一位都初始化为0。布隆过滤器定义有k个hash函数,对输入的数据生成k个hash值,定义有一个map函数将k个hash值映射到bitmap的k个位。如下图:
存入时将数据对应的bitmap中的k个位都置为1,检索时只需要比对数据对应的k个位是否都为1。布隆过滤器不允许从中删除数据,因为删除数据时可能会影响其他数据对应的位,造成删除其他数据。
三、布隆过滤器的实现(python)
Bloom.py
import random from bitmap import BitMap class BloomFilter: def __init__(self, mapsize=160000, max_node_size=