【发布时间】:2014-07-28 17:26:47
【问题描述】:
这段代码
foreach my $ti (@forward){
my $new_bs = %blast_values->{ $ti }->{"bitscore"};
if($new_bs > $fbs){
$fti = $ti;
$fbs = $new_bs;
}
}
my $fqstart = %blast_values->{ $fti }->{"qstart"};
my $fqend = %blast_values->{ $fti }->{"qend"};
my $fsstart = %blast_values->{ $fti }->{"sstart"};
my $fsend = %blast_values->{ $fti }->{"send"};
最初是通过子程序调用完成的:
my ($fti, $fqstart, $fqend, $fsstart, $fsend, $fbs) = best_one(\@forward,\%blast_values);
它在子例程中的位置:
my @forward = @{$_[0]};
my %blast_values = %{$_[1]};
但是,子例程版本的运行速度比本文顶部显示的代码慢了大约 40 倍。子程序版本是相同的代码,只是移入子程序,然后返回指示的标量值。如果我让它运行完成,该子例程将被调用大约 30K 次,但我从来没有这样做过,因为它需要大约 1800 秒。将调试输出行放在子例程中的“foreach”之前,并且在运行期间输出行之间存在明显的延迟,大约为 1 秒,而对于 perl 主要部分中的版本,没有可测量的延迟(所以
该数组通常非常小,只有 1 或 2 个(99% 的时间)条目,很少达到 12 个。另一方面,哈希非常非常大。它有 150 万个键,每个键有 6 个值,可由子键访问。两者都是通过引用传递的,所以它们的内容大小真的不应该重要。
造成这种延迟的原因是什么?我不记得 Perl 子例程调用有这么多的调用开销,并且输入参数是通过引用传递的,所以它不必复制巨大的散列。 (尽管执行速度表明它可能正在这样做。)
Centos 5 上的 Perl 5.8.8。
【问题讨论】:
-
为什么要复制 (
my @forward = @{$_[0]}; my %blast_values = %{$_[1]};)?使用my ($forward, $blast_values) = @_; -
my ($forward, $blast_values) = @_;及以后使用 $forward->[x] 和 $blast_values->{y}。
标签: arrays performance perl hash