这是通过一个Perl数组迭代最好的实现(在速度和内存使用方面)? 有没有更好的办法? ( @Array
不必保留)。
实施1
foreach (@Array)
{
SubRoutine($_);
}
实施2
while($Element=shift(@Array))
{
SubRoutine($Element);
}
实施3
while(scalar(@Array) !=0)
{
$Element=shift(@Array);
SubRoutine($Element);
}
实施4
for my $i (0 .. $#Array)
{
SubRoutine($Array[$i]);
}
实施5
map { SubRoutine($_) } @Array ;
如果你只关心的元素@Array
,使用方法:
for my $el (@Array) {
# ...
}
要么
如果指数关系,使用方法:
for my $i (0 .. $#Array) {
# ...
}
或者,作为perl
5.12.1,您可以使用:
while (my ($i, $el) = each @Array) {
# ...
}
如果您同时需要元素及其指数的循环体, 我期望 利用each
是最快的,但随后 你会放弃兼容5.12.1前perl
秒。
其他一些模式比这些可能是在某些情况下适当的。
IMO,实现#1是典型的做空和习惯为Perl胜过别人,单靠。 这三个选项的基准可能会为您提供洞察速度,至少。
图1是从图2和3基本上不同,因为它的叶子在间歇阵列,而其它两个保留空白。
我会说#3是很古怪,可能效率较低,所以忘了。
这让你#1和#2,和他们不这样做同样的事情,因此不能比其他“更好”。 如果数组很大,你并不需要保留它, 一般范围将处理它( 但是见 注 ),所以一般 ,#1仍然是最清晰,最简单的方法。 移动每个元素断不会加速任何东西。 即使有必要摆脱参考阵列,我只是去:
undef @Array;
当完成。
- 注 :包含数组的范围子程序实际上保持阵列和重新使用的空间下一次。 一般情况下 ,这应该是罚款(见注释)。
在单线打印元件或阵列。
打印$ _的(@array);
注:请记住,$ _内部参考@array的环路的元素。 在$ _将@array反映所做的任何更改; 恩。
my @array = qw( 1 2 3 );
for (@array) {
$_ = $_ *2 ;
}
print "@array";
输出:2 4 6
确定这样的问题来作为比较基准的最佳方式:
use strict;
use warnings;
use Benchmark qw(:all);
our @input_array = (0..1000);
my $a = sub {
my @array = @{[ @input_array ]};
my $index = 0;
foreach my $element (@array) {
die unless $index == $element;
$index++;
}
};
my $b = sub {
my @array = @{[ @input_array ]};
my $index = 0;
while (defined(my $element = shift @array)) {
die unless $index == $element;
$index++;
}
};
my $c = sub {
my @array = @{[ @input_array ]};
my $index = 0;
while (scalar(@array) !=0) {
my $element = shift(@array);
die unless $index == $element;
$index++;
}
};
my $d = sub {
my @array = @{[ @input_array ]};
foreach my $index (0.. $#array) {
my $element = $array[$index];
die unless $index == $element;
}
};
my $e = sub {
my @array = @{[ @input_array ]};
for (my $index = 0; $index < $#array; $index++) {
my $element = $array[$index];
die unless $index == $element;
}
};
my $f = sub {
my @array = @{[ @input_array ]};
while (my ($index, $element) = each @array) {
die unless $index == $element;
}
};
my $count;
timethese($count, {
'1' => $a,
'2' => $b,
'3' => $c,
'4' => $d,
'5' => $e,
'6' => $f,
});
而对x86_64的Linux的GNU的线程多建的Perl 5,24版,颠覆1(v5.24.1)运行此
我得到:
Benchmark: running 1, 2, 3, 4, 5, 6 for at least 3 CPU seconds...
1: 3 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 12560.13/s (n=39690)
2: 3 wallclock secs ( 3.18 usr + 0.00 sys = 3.18 CPU) @ 7828.30/s (n=24894)
3: 3 wallclock secs ( 3.23 usr + 0.00 sys = 3.23 CPU) @ 6763.47/s (n=21846)
4: 4 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 9596.83/s (n=30230)
5: 4 wallclock secs ( 3.20 usr + 0.00 sys = 3.20 CPU) @ 6826.88/s (n=21846)
6: 3 wallclock secs ( 3.12 usr + 0.00 sys = 3.12 CPU) @ 5653.53/s (n=17639)
所以“的foreach(@array)”的两倍左右的速度是其他。 所有的人都非常相似。
@ikegami还指出,目前在比速度等这些implimentations不少差异。