gpt4 book ai didi

perl - 在 Perl 中,为什么绑定(bind)数组这么慢?

转载 作者:行者123 更新时间:2023-12-04 06:10:09 25 4
gpt4 key购买 nike

在我的测试中,我注意到迭代绑定(bind)数组的速度最多只有使用内部访问器方法(FETCHFETCHSIZE)的一半。以下基准测试显示了该问题:

{package Array;
sub new {
my $class = shift;
tie my @array, $class, [@_];
\@array
}
sub TIEARRAY {
my ($class, $self) = @_;
bless $self => $class;
}
sub FETCH {$_[0][$_[1]]}
sub FETCHSIZE {scalar @{$_[0]}}
}

use List::Util 'sum';
use Benchmark 'cmpthese';

for my $mag (map 10**$_ => 1 .. 5) {

my $array = Array->new(1 .. $mag);
my $tied = tied(@$array);
my $sum = sum @$array;

print "$mag: \n";
cmpthese -2 => {
tied => sub {
my $x = 0;
$x += $_ for @$array;
$x == $sum or die $x
},
method => sub {
my $x = 0;
$x += $tied->FETCH($_) for 0 .. $tied->FETCHSIZE - 1;
$x == $sum or die $x
},
method_while => sub {
my $x = 0;
my $i = 0; $x += $tied->FETCH($i++) while $i < $tied->FETCHSIZE;
$x == $sum or die $x
},
method_while2 => sub {
my $x = 0;
my $i = 0;
$x += tied(@$array)->FETCH($i++)
while $i < tied(@$array)->FETCHSIZE;
$x == $sum or die $x
},
method_while3 => sub {
my $x = 0;
my $i = 0;
while ($i < tied(@$array)->FETCHSIZE) {
local *_ = \(tied(@$array)->FETCH($i++));
$x += $_
}
$x == $sum or die $x
},
};
print "\n";
}

数组大小为 1000,基准返回:

1000:
速率绑定(bind) method_while3 method_while2 method_while 方法
并列 439/s -- -40% -51% -61% -79%
method_while3 728/s 66% -- -19% -35% -65%
method_while2 900/s 105% 24% -- -19% -57%
method_while 1114/s 154% 53% 24% -- -47%
方法 2088/s 375% 187% 132% 87% --

我省略了其他运行,因为数组的大小不会对相对速度产生有意义的变化。
method当然是最快的,因为它不会在每次迭代时检查数组的大小,但是 method_whilemethod_while2似乎以与 for 相同的方式在绑定(bind)阵列上运行循环,甚至更慢的 method_while2是绑定(bind)数组的两倍。

甚至添加 $_ 的本地化并将别名分配给 method_while2method_while3导致执行速度比绑定(bind)数组快 66%。
for 中发生了哪些额外的工作 method_while3 中未发生的循环?有什么办法可以提高捆绑阵列的速度吗?

最佳答案

每次使用绑定(bind)数组时,它都必须查找绑定(bind)对象,然后查找方法,然后调用它们。对于您的其他版本,您在编译时或循环之前执行部分或全部查找,而不是在每次访问时进行。

(顺便说一下,method 和其他 method_* 版本之间的速度比较就是一个很好的例子:你会看到这样做的代价 FETCHSIZE ,即使已经找到了绑定(bind)的对象。现在将该成本应用于接触数组的每个操作。)

关于perl - 在 Perl 中,为什么绑定(bind)数组这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5518204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com