【发布时间】:2014-05-15 12:42:21
【问题描述】:
在一个 Perl 脚本中,我构建了一个大散列(大约 10 GB),大约需要 40 分钟,其中包含大约 1 亿个键。接下来我要遍历哈希的键,如下所示:
foreach my $key (keys %hash) {
但是,这条线需要 1 小时 20 分钟来评估!一旦进入 for 循环,代码就会快速遍历整个哈希。
为什么进入forloop需要这么长时间?我怎样才能加快这个过程?
【问题讨论】:
在一个 Perl 脚本中,我构建了一个大散列(大约 10 GB),大约需要 40 分钟,其中包含大约 1 亿个键。接下来我要遍历哈希的键,如下所示:
foreach my $key (keys %hash) {
但是,这条线需要 1 小时 20 分钟来评估!一旦进入 for 循环,代码就会快速遍历整个哈希。
为什么进入forloop需要这么长时间?我怎样才能加快这个过程?
【问题讨论】:
foreach my $key (keys %hash) {
此代码将首先创建一个列表,其中包含 %hash 中的所有键,并且您说您的 %hash 很大,然后需要一段时间才能完成。尤其是当您因为实际内存用完而开始将内存交换到磁盘时。
您可以使用while (my ($key, $value) = each %hash) { 来迭代该哈希,而这个不会创建那个巨大的列表。如果你正在交换,这将快得多,因为你不会了。
【讨论】:
each() 被认为可以接受的少数情况之一。尽管在其中放置一些大警告可能会很好,解释原因,并提请注意其微妙的性质以防将来的编辑。
有两种迭代哈希的方法,各有优缺点。
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 %h、values %h 或 each %h,那么循环将无法正常工作,因为 %h 只有 1 个迭代器【讨论】:
each 的另一个缺点是它使用的迭代器属于%h。如果循环内的代码调用了 keys %h、values %h 或 each %h,那么循环将无法正常工作,因为 %h 只有 1 个迭代器。