最好的方法来遍历Perl数组
哪个是最好的实现(在速度和内存使用方面)迭代通过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 ;
-
在速度方面:#1和#4,但在大多数情况下并不多。
你可以编写一个基准来确认,但是我怀疑你会发现#1和#4稍微快一点,因为迭代工作是用C而不是Perl来完成的,并且不会发生数组元素的不必要的拷贝。 (
$_
被别名到#1中的元素,但#2和#3实际上是从数组中复制标量)。#5可能是相似的。
-
在内存使用方面:除了#5之外,它们都是一样的。
for (@a)
是特殊的,以避免压扁数组。 循环迭代数组的索引。 -
在可读性方面:#1。
-
灵活性方面:#1 /#4和#5。
#2不支持错误的元素。 #2和#3具有破坏性。
如果您只关心@Array
的元素,请使用:
for my $el (@Array) { # ... }
要么
如果指标很重要,请使用:
for my $i (0 .. $#Array) { # ... }
或者,从perl
5.12.1开始,你可以使用:
while (my ($i, $el) = each @Array) { # ... }
如果你需要循环体中的元素和索引, 我期望 使用each
成为最快的,但是 你会放弃5.12.1之前的兼容性。
在某些情况下,除此之外的其他一些模式可能是合适的
国际海事组织(IMO)的实施#1是典型的,对于Perl来说简短而惯用的就是胜过其他人。 这三个选项的基准可能会让你对速度有所了解,至less。
1与2和3基本上是不同的,因为它离开了arrays,而另外两个空着。
我会说#3是相当古怪,可能效率较低,所以忘记了。
这会让你留下#1和#2,他们不会做同样的事情,所以一个人不能比另一个“更好”。 如果数组很大,并且不需要保留它, 一般范围将会处理它( 但请参见 NOTE ),所以通常 #1仍然是最清晰和最简单的方法。 closures每个元素不会加快速度。 即使有需要从参考中释放数组,我只需要:
undef @Array;
完成后。
- 注意 :包含该数组作用域的子例程实际上保留该数组,并在下一次重新使用该空间。 一般来说 ,这应该没问题(见评论)。
在单行中打印元素或数组。
打印$ _ for(@array);
注意:请记住,$ _在内部是指循环中@array的元素。 $ _中所做的任何更改将反映在@array中; 恩。
my @array = qw( 1 2 3 ); for (@array) { $_ = $_ *2 ; } print "@array";
输出:2 4 6