加快我对HyperLogLog算法的实施

时间:2014-05-15 19:03:25

标签: perl pack unpack hyperloglog

我自己实现了HyperLogLog algorithm。它工作得很好,但有时我必须获取很多(大约10k-100k)的HLL结构并合并它们。

我将它们作为位字符串存储,所以首先我必须将每个位字符串转换为存储桶。由于HLL很多,所以它需要的时间比我想要的要长。

目前大约80%的运行时为每个HLL调用一行代码:

my @buckets = map { oct '0b'.$_ } unpack('(a5)1024', $bitstring);

有没有办法更快地完成?

如果我们留下HyperLogLog的定义,可以这样解释任务:假设$bitstring由1024个5位计数器组成(因此每个计数器的值最多可达32)我们必须将其转换为数组1024个整数。

1 个答案:

答案 0 :(得分:6)

a表示任意零填充二进制数据。在这里,您将该数据视为ASCII文本,但它只能包含10!这是低效的,因为a5最终使用五个字节。最简单,最有效的解决方案是为每个计数器存储一个8位数字,然后:my @buckets = unpack 'C1024', $bitstring

如果你只想在每个计数器上存储5位,那么你最终会节省很少的内存而非常麻烦。你必须使用像这样疯狂的东西来进行往返转换:

my $bitstring = pack "(b5)1024", map { sprintf "%b", $_ } @buckets;
@buckets = map { oct "0b$_" } unpack "(b5)1024", $bitstring;