Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

前面几篇文章,我们分别讲解了:

本章将继续分析和比较他们之间的区别,以及分别在什么场景下选择什么算法。

1. Set(集合)

Set是常见数据结构,代表确定且无重复元素的集合。

  • 核心原理:直接存储元素本身或完整哈希值,常见实现有哈希集合(HashSet)和树集合(TreeSet)。
  • 精确性:100%精确,能准确判断元素是否在集合中。
  • 空间效率:低,空间复杂度O(n),元素大时内存消耗可观。
  • 时间效率:哈希集合插入/查询平均O(1),合并/求交集需遍历。
  • 典型应用场景:数据库、缓存的成员关系判断;不大的黑名单/白名单列表;编程语言日常去重。
  • 优点:精确无误,功能全面可取出所有元素。
  • 缺点:内存消耗大,无法处理海量数据。

2. Bitmap(位图)

Bitmap通过bit数组表征集合,数组位对应特定元素。

  • 核心原理:全集U中元素有唯一整数索引,若元素存在,对应下标bit设为1,否则为0。
  • 精确性:100%精确。
  • 空间效率:高,但取决于全集大小,若全集[0, n),只需n / 8字节。
  • 时间效率:插入/查询O(1),合并/求交集可通过位运算高效操作。
  • 典型应用场景:用户签到、在线状态统计;标签系统人群筛选;数据库快速查询索引。
  • 优点:全集已知且不大时,时空效率极高,精确且支持快速集合运算。
  • 缺点:依赖元素密集整数映射,元素ID稀疏会浪费空间;无法处理非数值型数据,需先哈希映射。

3. 布隆过滤器

布隆过滤器是概率型数据结构,判断元素是否一定不存在或可能存在。

  • 核心原理:长度为m的bit数组,k个哈希函数。添加元素时,经k个哈希函数映射位置并置1;查询时,k个位置都为1则可能存在,有一个为0则一定不存在。
  • 精确性:概率性,有误判率但不会漏判,可调整m和k控制误判率。
  • 空间效率:极高,只需固定大小bit数组,空间复杂度O(m)。
  • 时间效率:插入/查询O(k),通常为O(1)。
  • 典型应用场景:缓存穿透解决;爬虫URL去重;垃圾邮件过滤。
  • 优点:空间和查询效率远超一般算法,安全不漏报。
  • 缺点:有误判率,无法删除元素(计数布隆过滤器可删但需更多空间)。

4. HyperLogLog

HyperLogLog是估算大数据集基数的概率算法,回答集合大概有多少不重复元素。

  • 核心原理:基于统计比特串前缀连续0的最大数目估算基数,元素经哈希函数转化为比特串,观察连续0个数,用分桶平滑极端值。
  • 精确性:估算,有标准误差,约0.81%。
  • 空间效率:极致,通常只需12KB或更少内存。
  • 时间效率:添加元素O(1),合并效率高。
  • 典型应用场景:网站独立访客(UV)统计;数据库COUNT(DISTINCT …)近似计算;大规模日志分析统计独立事件数。
  • 优点:计算巨大数据集基数时,空间复杂度优势大,合并操作方便。
  • 缺点:结果为近似值,只能用于基数估算,无法判断单个元素是否存在。

5. 总结对比表格

特性 Set Bitmap 布隆过滤器 HyperLogLog
核心问题 精确成员查询 精确成员查询 可能存在 / 一定不存在 大概有多少不重复元素
精确性 100%精确 100%精确 概率性(有误判) 近似(有误差)
空间效率 低 O(n) (依赖全集密度) 极高 O(m) 极致 O(log log n)
关键优势 精确,功能全 精确,集合运算快 空间效率极高,安全(不漏报) 海量数据基数估算
致命弱点 内存消耗大 1. 一般只支持整数类型;
2. 稀疏数据下空间浪费
有误判率,无法删除 只能计数,不能查询成员
典型应用 通用去重,小规模数据 标签系统,状态统计 缓存穿透,爬虫去重 网站UV统计

6. 如何选择?

选择取决于业务需求:

  1. 需100%精确判断元素是否存在
    • 数据量不大用Set
    • 元素是密集整数用Bitmap
  2. 数据量巨大且可接受小概率误判:判断存在性用布隆过滤器
  3. 只需知道大概不重复元素数量:统计基数用HyperLogLog
  4. 组合使用案例:大型网站统计系统,布隆过滤器防缓存穿透,HyperLogLog统计日活,Bitmap用于用户画像圈选,Set存储后台管理员列表。

评论