最好的方法来遍历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