加快HyperLogLog算法的实现
我自己实现了。它工作得很好,但有时我必须获取大量(大约10k-100k)HLL结构并合并它们 我将它们存储为一个位字符串,因此首先我必须将每个位字符串转换为bucket。因为有很多HLL的,它需要更多的时间比我想它 目前,大约80%的运行时使用这行代码,每个HLL调用一次:加快HyperLogLog算法的实现,perl,pack,unpack,hyperloglog,Perl,Pack,Unpack,Hyperloglog,我自己实现了。它工作得很好,但有时我必须获取大量(大约10k-100k)HLL结构并合并它们 我将它们存储为一个位字符串,因此首先我必须将每个位字符串转换为bucket。因为有很多HLL的,它需要更多的时间比我想它 目前,大约80%的运行时使用这行代码,每个HLL调用一次: my@bucket=map{oct'0b'.$}解包(“(a5)1024',$bitstring) 有什么办法可以更快地完成吗 如果我们不考虑HyperLogLog的定义,这个任务可以这样解释:假设$bitstring由10
my@bucket=map{oct'0b'.$}解包(“(a5)1024',$bitstring)代码>
有什么办法可以更快地完成吗
如果我们不考虑HyperLogLog的定义,这个任务可以这样解释:假设$bitstring
由1024个5位计数器组成(因此每个计数器的值最多可达32),我们必须将其转换为1024个整数的数组。a
表示任意的零填充二进制数据。这里,您将该数据视为ASCII文本,但它只能包含1
和0
!这是低效的,因为a5
最终使用了五个字节。最简单、最有效的解决方案是为每个计数器存储一个8位数字,然后:my@bucket=unpack'C1024',$bitstring
如果您只想在每个计数器上存储5位,那么最终将节省很少的内存,从而带来很多麻烦。在往返转换过程中,您必须使用像这样疯狂的东西:
my $bitstring = pack "(b5)1024", map { sprintf "%b", $_ } @buckets;
@buckets = map { oct "0b$_" } unpack "(b5)1024", $bitstring;
您能提供一些$bitstring的示例吗?还有运行需要多长时间,什么是可以接受的?@michael,这是一个字符串,像“101011…”这样简单。它的长度是5120个符号。请注意,有一个cpan模块用于此:@Miller谢谢,我不知道。有趣的是,它确实通过文件导出和导入,与Bloom::更快的方式相同。正因为如此,我不得不自己制作布卢姆过滤器。他们到底在想什么?为什么不给我一根绳子,我可以把它放在我想要的任何地方?我的blooms和HLL都使用Redis而不是文件,考虑到Redis位操作和Lua脚本,这非常方便(我知道Redis内置了HLL,但它们对我来说太大了)。“最简单、最有效的解决方案是为每个计数器存储一个8位数字”——这很有意义。我想说的是,我可以拥有高达36k的HLL,这并不太多,因此我可以再增加40%的内存;但后来我意识到这是一个错误,事实上,通过当前的实现,我可以拥有数亿个:)我应该回到绘图板上…%)所以,在画板之前多出一分钱——“拆包‘C1024’”,实际上至少快了4倍。谢谢