0 超大集合去重

在数学上把一个集合不重复元素的个数称为集合的基数(cardinality,也有叫做势),这类问题可以称为基数统计问题.

典型的需求是:

  • 统计一个月内某App 的DAU ,MAU
  • 统计某个网页UV

容易想到的思路:

  • java set

    假如有个1亿个不重复的元素,每个4个字节,则内存开销 400M

  • BitMap 位图

    不保存实际使用的元素,只用 1bit 标识某个元素是否出现过。位图占用的内存和元素的值域有关,因为我们需要把值域映射到这个大的比特数组上。假设元素的值域是 [1,1亿],那么采用位图需要的内存就是 100000000∗1bit / 8 ≈12MB 。该方法也能够精确的计算出不重复元素的数量,比起Set来说,内存占用确实减少很多,但是如果需要统计上千个模块或者业务的数据,那么内存消耗依然很大

  • 布隆过滤器(bloom filter)

    类似于位图,也是一个大的bit数组,存储的数据通过多个哈希函数计算,映射到比特数组的多个bit中,进而判断一个元素是否在集合中。布隆过滤器具有一定的误判率,占用的内存比位图略小,和误判率有关,误判率越低,需要的内存越大

  • hyperLogLog (HLL)

    HyperLogLog Counting算法以损失一定准确性为代价,能够使用极少的内存统计集合的基数,常常被用于统计产品的日活、月活,独立访客数等等场景。在Redis中也支持HyperLogLog数据结构,并且对内存的使用做了一些优化

1 分享一个国外大学的学习数据结构的网址

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

2 B树 ,B+ 树

3

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐