Perl需要花费很长时间来评估:密钥%hash /遍历大散列

jos*_*hlk 4 perl hash hashmap

在Perl脚本中,我构建了一个大的哈希值(大约10 GB),大约需要40分钟,大约有1亿个密钥.接下来我想循环遍历哈希的键,如下所示:

foreach my $key (keys %hash) {
Run Code Online (Sandbox Code Playgroud)

然而,这条线需要1小时20分钟来评估!一旦进入for循环,代码就会快速运行整个哈希.

为什么进入forloop需要这么长时间?我怎样才能加快这个过程?

Lee*_*hem 8

foreach my $key (keys %hash) {
Run Code Online (Sandbox Code Playgroud)

此代码将创建一个包含所有键的列表%hash,并且您说您的键%hash很大,然后需要一段时间才能完成.特别是如果你开始将内存交换到磁盘,因为你没有真正的内存.

您可以使用while (my ($key, $value) = each %hash) {迭代该哈希值,而这个哈希值不会创建那么大的列表.如果你交换,这将是快,因为你不会了.

  • `S /阵列/列表/ g` (2认同)

jay*_*ngh 7

迭代哈希有两种方法,两者都有其优点和缺点.

方法1:

foreach my $k (keys %h)
{
  print "key: $k, value: $h{$k}\n";
}
Run Code Online (Sandbox Code Playgroud)

优点:

  • 可以按键对输出进行排序.

缺点:

  • 它会创建一个临时列表来保存密钥,以防您的哈希值非常大,最终会占用大量内存资源.

方法2:

while ( ($k, $v) = each %h )
{
  print "key: $k, value: $h{$k}\n";
}
Run Code Online (Sandbox Code Playgroud)

优点:

  • 这使用非常少的内存,因为每次each调用它只返回一对(key,value)元素.

缺点:

  • 您无法按键订购输出.
  • 它使用的迭代器属于%h.如果循环中的代码调用了某些东西keys %h,values %h或者each %h,那么循环将无法正常工作,因为%h只有1个迭代器

  • 使用`each`的另一个问题是它使用的迭代器属于`%h`.如果循环中的代码调用`keys%h`,`values%h`或`each%h`,那么循环将无法正常工作,因为`%h`只有1个迭代器. (2认同)