【问题标题】:Perl takes a long time to evaluate: keys %hash / iterate through a large hashPerl 需要很长时间来评估:keys %hash / iterate through a large hash
【发布时间】:2014-05-15 12:42:21
【问题描述】:

在一个 Perl 脚本中,我构建了一个大散列(大约 10 GB),大约需要 40 分钟,其中包含大约 1 亿个键。接下来我要遍历哈希的键,如下所示:

foreach my $key (keys %hash) {

但是,这条线需要 1 小时 20 分钟来评估!一旦进入 for 循环,代码就会快速遍历整个哈希。

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

【问题讨论】:

    标签: perl hash hashmap


    【解决方案1】:
    foreach my $key (keys %hash) {
    

    此代码将首先创建一个列表,其中包含 %hash 中的所有键,并且您说您的 %hash 很大,然后需要一段时间才能完成。尤其是当您因为实际内存用完而开始将内存交换到磁盘时。

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

    【讨论】:

    • 太棒了!之前我的脚本需要 2 个小时才能运行,现在需要 8 分钟!!谢谢
    • 做了一些小的澄清更改。
    • @ikegami 感谢您的改进。
    • 这是在哈希上使用each() 被认为可以接受的少数情况之一。尽管在其中放置一些大警告可能会很好,解释原因,并提请注意其微妙的性质以防将来的编辑。
    【解决方案2】:

    有两种迭代哈希的方法,各有优缺点。

    方法一:

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

    优点:

    • 可以按键排序输出。

    缺点:

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

    方法二:

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

    优点:

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

    缺点:

    • 您不能按键排序输出。
    • 它使用的迭代器属于%h。如果循环内的代码调用了 keys %hvalues %heach %h,那么循环将无法正常工作,因为 %h 只有 1 个迭代器

    【讨论】:

    • 使用each 的另一个缺点是它使用的迭代器属于%h。如果循环内的代码调用了 keys %hvalues %heach %h,那么循环将无法正常工作,因为 %h 只有 1 个迭代器。
    • 谢谢@cjm。太好了,我不知道。将添加到答案。欣赏它。
    • 是的,这就是问题所在。为明确的答案干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    相关资源
    最近更新 更多