Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
加快HyperLogLog算法的实现_Perl_Pack_Unpack_Hyperloglog - Fatal编程技术网

加快HyperLogLog算法的实现

加快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

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

我将它们存储为一个位字符串,因此首先我必须将每个位字符串转换为bucket。因为有很多HLL的,它需要更多的时间比我想它

目前,大约80%的运行时使用这行代码,每个HLL调用一次:

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倍。谢谢