#基数 #hyper-log-log #sketch #概率 #distinct-count

cardinality-estimator

一个用于估计流或数据集中不同元素个数的crate

3 个稳定版本

1.0.2 2024年5月21日
1.0.1 2024年5月3日

#261算法

Download history 263/week @ 2024-04-27 65/week @ 2024-05-04 2/week @ 2024-05-11 219/week @ 2024-05-18 14/week @ 2024-05-25 30/week @ 2024-06-01 53/week @ 2024-06-08 32/week @ 2024-06-15 42/week @ 2024-06-22 26/week @ 2024-06-29 17/week @ 2024-07-06 22/week @ 2024-07-13 107/week @ 2024-07-20 157/week @ 2024-07-27

每月305 次下载

Apache-2.0

440KB
982

cardinality-estimator

build docs.rs crates.io License

cardinality-estimator 是一个Rust crate,旨在以高效的方式估计流或数据集中不同元素的数量。该库使用HyperLogLog++,具有优化的低内存占用和高度精确的方法,适用于大规模数据分析任务。我们在大规模机器学习中使用 cardinality-estimator,在请求的多个维度上计算基数特征。

概述

我们的 cardinality-estimator 在内存使用、延迟和精度方面都非常高效。这是通过利用独特的数据结构设计、高效算法以及HyperLogLog++对高基数范围的优化来实现的。

入门指南

要使用 cardinality-estimator,请将其添加到您的 Cargo.toml 中的 [dependencies]

[dependencies]
cardinality-estimator = "1.0.0"

然后,在您的Rust程序中导入 cardinality-estimator

use cardinality_estimator::CardinalityEstimator;

let mut estimator = CardinalityEstimator::<12, 6>::new();
estimator.insert("test");
let estimate = estimator.estimate();

println!("estimate = {}", estimate);

请参阅我们仓库中的 示例基准测试,了解更多复杂场景。

低内存占用

cardinality-estimator 通过利用高效的数据存储格式实现低内存占用。数据以三种不同的表示形式存储 - SmallArrayHyperLogLog,具体取决于基数范围。例如,对于基数为0到2的情况,只使用 8字节 的堆栈内存和0字节的堆内存。

低延迟

该crate通过使用编译器提示进行自动向量化切片操作,实现低延迟。随着更多数据的插入,动态存储和更新零寄存器和寄存器谐波和,从而实现快速的估计操作。

高精度

通过为小基数范围使用精确计数以及为较大范围使用带有LogLog-Beta偏差校正的HyperLogLog++,基数估计器实现了高精度。这为大型基数提供了低至0.02%的预期误差率。

基准测试

要运行基准测试,您首先需要安装 cargo-criterion 二进制文件

cargo install cargo-criterion

然后以 JSON 格式输出基准测试结果以供进一步分析

make bench

我们已经将基数估计器与其他几个生态系统中的 crate 进行了基准测试

请注意,hyperloglogprobabilistic-collections crate 中存在基于提供的 probability 计算精度 p 的错误

  • 错误的公式:p = (1.04 / error_probability).powi(2).ln().ceil() as usize;
  • 正确的公式:p = (1.04 / error_probability).powi(2).log2().ceil() as usize;

我们正在努力使 cardinality-estimator 成为 Rust 中最快的、最轻量级的和最精确的基数估计工具。

以下基准测试是在 Linux 笔记本电脑上执行的,使用 13th Gen Intel(R) Core(TM) i7-13800H 处理器,并将编译器标志设置为 RUSTFLAGS=-C target-cpu=native

内存使用情况

Cardinality Estimators Memory Usage

下表比较了不同基数估计器的内存使用情况。每个单元格中的数字表示在每次测量的基数下 栈内存字节 / 堆内存字节 / 堆内存块

我们的 cardinality-estimator 在所有不同的基数下都实现了最低的栈和堆内存分配。

请注意,hyperloglogplus 实现的内存使用量尤其高,特别是对于基数大于 256 的情况。

基数 cardinality_estimator amadeus_streaming probabilistic_collections hyperloglog hyperloglogplus
0 8 / 0 / 0 48 / 4096 / 1 128 / 4096 / 1 120 / 4464 / 2 160 / 0 / 0
1 8 / 0 / 0 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 36 / 1
2 8 / 0 / 0 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 36 / 1
4 8 / 16 / 1 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 92 / 2
8 8 / 48 / 2 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 188 / 3
16 8 / 112 / 3 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 364 / 4
32 8 / 240 / 4 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 700 / 5
64 8 / 496 / 5 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 1400 / 13
128 8 / 1008 / 6 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 3261 / 23
256 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 10361 / 43
512 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 38295 / 83
1024 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 146816 / 163
2048 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
4096 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
8192 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
16384 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
32768 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
65536 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
131072 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
262144 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
524288 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194
1048576 8 / 4092 / 7 48 / 4096 / 1 128 / 4096 / 1 120 / 4096 / 1 160 / 207711 / 194

插入性能

Cardinality Estimators Insert Time

下表表示每个元素的插入时间(纳秒)。

我们的 cardinality-estimator 在大多数基数下都表现出最低的插入时间。

基数 cardinality-estimator amadeus-streaming probabilistic-collections hyperloglog hyperloglogplus
0 0.64 88.12 70.19 82.69 17.45
1 2.42 91.5 80.2 131.86 60.65
2 2.21 44.3 45.34 81.48 34.96
4 6.9 25.59 24.85 54.38 36.22
8 7.27 15.62 17.92 43.54 35.55
16 6.99 12.15 14.44 37.24 33.4
32 7.9 9.6 12.78 34.23 32.49
64 10.14 8.97 11.86 32.55 39.04
128 15.47 8.52 11.49 31.76 48.37
256 13.42 8.01 11.24 31.44 65.58
512 9.92 8.1 11.11 31.34 100.25
1024 8.32 8.14 12.52 31.73 171.71
2048 7.31 7.92 12.52 32.03 120.71
4096 7.11 8.01 11.04 32.73 63.5
8192 8.81 8.02 10.97 33.08 37.36
16384 8.08 8.01 11.03 32.75 22.24
32768 6.55 7.96 11.01 32.37 13.3
65536 5.35 7.96 10.96 31.95 8.41
131072 4.48 7.9 10.97 31.71 5.71
262144 3.91 7.95 10.95 31.52 4.26
524288 3.58 7.64 10.95 31.47 3.47
1048576 3.35 7.95 10.95 31.47 3.04

估计性能

Cardinality Estimators Estimate Time

下表表示每次调用的估计时间(纳秒)。

我们的 cardinality-estimator 在大多数基数下,特别是 128 以下的较小基数中,都显示了最低的估计时间。

请注意,amadeus-streaming 的实现对于估计操作也非常有效,然而,如上表所示,它的内存使用量更高。实现 probabilistic-collectionshyperloglogplushyperloglogplus 的估计时间要高得多,尤其是在高基数情况下。

基数 cardinality-estimator amadeus-streaming probabilistic-collections hyperloglog hyperloglogplus
0 0.18 7.9 15576.4 125.03 24.89
1 0.18 9.19 15619.8 134.3 64.62
2 0.18 9.18 15615.5 134.4 70.51
4 0.18 9.2 15642.7 134.01 89.16
8 0.18 9.19 15611.1 134.41 132.0
16 0.18 9.19 15621.6 134.39 211.4
32 0.18 9.19 15637.1 130.58 357.55
64 0.18 9.19 15626 130.26 619.95
128 0.18 9.18 15640.8 130.33 1134.12
256 11.31 9.09 15668 133.5 2205.7
512 11.3 9.09 15652 129.58 4334.05
1024 11.31 9.09 15687.1 129.79 8392.59
2048 11.28 9.11 15680.4 129.8 8.08
4096 11.29 38.63 15803.4 129.49 4342.07
8192 11.28 38.98 23285 129.51 4345.7
16384 11.29 38.17 26950.7 132.96 4341.9
32768 6.02 10.86 31168 7674.3 4334.98
65536 6.05 4.1 33123.8 40986.4 4327.48
131072 6.02 4.1 33772.4 42113.7 4327.29
262144 6.02 4.11 34711.7 43587 4329.63
524288 6.02 4.1 36091.2 43582.8 4327.8
1048576 6.02 4.11 37877.1 45055.3 4327.37

错误率

Cardinality Estimators Error Rate

下表展示了在给定基数下,估计器在随机元素上运行100次后的平均绝对相对误差。

我们的 cardinality-estimator 在性能上与 amadeus-streaminghyperloglog 估计器相当,但在基数高达128时,具有特别小的低错误率。

请注意,probabilistic-collections 实现在基数 >=32768 时的估计操作中似乎存在错误。

基数 cardinality_estimator amadeus_streaming probabilistic_collections hyperloglog hyperloglogplus
0 0.0000 0.0000 0.0000 0.0000 0.0000
1 0.0000 0.0000 0.0000 0.0000 0.0000
2 0.0000 0.0000 0.0000 0.0000 0.0000
4 0.0000 0.0000 0.0000 0.0000 0.0000
8 0.0000 0.0000 0.0000 0.0000 0.0000
16 0.0000 0.0019 0.0013 0.0025 0.0000
32 0.0000 0.0041 0.0031 0.0041 0.0000
64 0.0000 0.0066 0.0086 0.0078 0.0000
128 0.0000 0.0123 0.0116 0.0140 0.0000
256 0.0080 0.0097 0.0094 0.0084 0.0000
512 0.0088 0.0100 0.0087 0.0090 0.0000
1024 0.0080 0.0094 0.0101 0.0095 0.0000
2048 0.0092 0.0093 0.0090 0.0107 0.0100
4096 0.0099 0.0108 0.0113 0.0114 0.0103
8192 0.0096 0.0095 0.0131 0.0126 0.0109
16384 0.0116 0.0107 0.0204 0.0229 0.0117
32768 0.0125 0.0109 1.46e14 0.0437 0.0116
65536 0.0132 0.0133 2.81e14 0.0143 0.0118
131072 0.0116 0.0121 1.41e14 0.0128 0.0127
262144 0.0137 0.0144 7.04e13 0.0122 0.0116
524288 0.0138 0.0136 3.52e13 0.0116 0.0121
1048576 0.0113 0.0124 1.76e13 0.0141 0.0110
平均 0.0064 0.0078 3.14e13 0.0101 0.0052

依赖项