首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何循环通过值为arrayref的HoA?

如何循环通过值为arrayref的HoA?
EN

Stack Overflow用户
提问于 2013-04-02 02:41:03
回答 2查看 69关注 0票数 0

我想让我的脚本尽可能的高效和快速地运行。下面是我创建HoA的方法。

代码语言:javascript
运行
AI代码解释
复制
use strict; use warnings; open(my $fh, '<', 'file.txt') or die $!;
my %HoA;
while (<$fh>){
    $_=~ s/\r//;
    chomp;
    my @cols = split(/\t/, $_);
    my $key = shift @cols;
    push( @{$HoA{$key}, @cols );
}

假设它提供了以下数据结构

代码语言:javascript
运行
AI代码解释
复制
%HoA = (
    'C1' => ['1', '3', '3', '3'],
    'C2' => ['3','2'],
    'C3' => ['1','3','3','4','5','5'],
    'C4' => ['3','3','4'],
    'C5' => ['1'],
);

现在假设对于HoA中的每个键,我希望将它的值(数组)和整个HoA传递到一个名为compute的子例程中。

这是我目前正在做的事情。

代码语言:javascript
运行
AI代码解释
复制
foreach my $key ( keys %HoA ) {
    compute($HoA{$key}, \%HoA);  # on the first iteration, this actually passes an aref to [1,3,3,3]
}

显然,$HoA{ $key }已经是对特定$key每个值的数组引用。

如果是这样的话,执行以下操作在效率方面是否有优势

代码语言:javascript
运行
AI代码解释
复制
push( @{$HoA{$key}, \@cols );

它产生以下数据结构

代码语言:javascript
运行
AI代码解释
复制
%HoA = (
    'C1' => [ ['1', '3'], ['3', '3'] ],
    'C2' => [ ['3','2'] ],
    'C3' => [ ['1','3'], ['3','4'], ['5','5'] ],
    'C4' => [ ['3','3','4'] ],
    'C5' => [ ['1'] ],
);

这会让我的脚本运行得更快吗?如果是这样,在这种情况下,我如何将每个键的值( array_ref)传递给子例程?一旦它在子例程中,我如何访问数组中的单个元素,而不在子例程中取消对整个array_ref的引用?另外,对于$hash_ref,如何访问每个array_ref?

下面是我目前使用的方法

代码语言:javascript
运行
AI代码解释
复制
sub compute{
# takes one param: an arrayref
my ($array_ref, $hash_ref) = @_;
    for my $p ( @{ $array_ref) ) {
        # do stuff
    }
    for my $x ( values %{ %hash_ref)) {
        # do stuff
    }
}
EN

回答 2

Stack Overflow用户

发布于 2013-04-02 02:47:16

由于代码中的取消引用,这可能会使代码运行速度变慢。此外,您需要扁平化每个散列条目指向的数组中包含的数组,如下所示:

代码语言:javascript
运行
AI代码解释
复制
my %h = ( a => [ [1, 2], [3, 4] ], b => [ [2, 3], [5, 6] ]); 
my $key = 'a';
my @all_items;
@all_items = map { @$_ } @{$h{$key}};

仅凭经验,在Perl中取消引用对象(即数组)的成本可能会非常高,因此使用较少引用的第一个方法应该会更快。但是你可以给这些东西计时。最好的做法是只编写代码,然后在对整个代码进行概要分析后,再考虑真正重要的部分。

票数 1
EN

Stack Overflow用户

发布于 2013-04-02 03:15:28

如果是这样的话,执行以下操作在效率方面是否有优势

push( @{$HoA{$key},\@cols );

不是的。首先,正确地创建数据结构

代码语言:javascript
运行
AI代码解释
复制
push @{ $HoA{$key} }, @cols;    # Copies the number to the anon array.

compute($_, \%HoA) for values %HoA;

总比稍后重新创建正确的数据结构要好。

代码语言:javascript
运行
AI代码解释
复制
push @{ $HoA{$key} }, \@cols;

compute([ map @$_, @$_ ], \%HoA) for values %HoA;  # But so does this.

通过切换,您最终将在已有工作的基础上完成适当的超集。

正如评论中提到的,你优化的是错误的东西。你说你的程序需要30-40秒才能运行。即使你将加载文件的时间减少到零,你的程序仍然需要29-39秒。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15755183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档