开发者

Which "for" loop should I use in Perl?

What are the arguments for using one of the for loops over the other to count through integers?

for my $i (0..$n) { ... }

for (my $i = 0; $i <= $n; $i开发者_StackOverflow++) { ... }


In your case, there isn't any difference.

In other use cases, in a for-each loop you don't have control of or access to the iterator.

Using your example syntax:

for my $i (0..10)
{
   print "$i";
   $i++;
}

The above actually creates a foreach loop - it's the same as saying foreach my $i (0..10). $i is a value returned from the list, not the iterator. The iterator is internal and you don't have any access to it; you can not control the flow of the loop.

The output from above will print 012345678910.

This:

for ( my $i = 0; $i++ ; $i <= 10)
{
    print $i;
    $i++;
}

That is an actual for loop. You are controlling and outputting the iterator. It will output: 0246810

In addition:

When you do for (1..$n) you are invoking the range operator vs. doing a simple comparison at the top of the loop. Performance differences, however, would be immeasurable.


The difference between the two styles of for loops in Perl is one of both clarity and efficiency.

When you look at for my $i (0 .. $n) {...} you can instantly see the range being used without having to mentally parse a larger expression.

With for (my $i = 0; $i <= $n; $i++) {...} there is quite a bit more to look at, and more places where errors can creep in.

In addition, foreach over a range is faster than the equivalent C-style loop as shown by the following benchmark:

use Benchmark 'cmpthese';

for my $mag (map 10**$_, 1 .. 6) {
    print "\n$mag:\n";
    cmpthese -2 => {
        loop => sub {my $x = 0; for (my $i = 0; $i <= $mag; $i++) {$x += $i}},
        each => sub {my $x = 0; for my $i (0 .. $mag) {$x += $i}},
    };
}

which prints:

10:
         Rate loop each
loop 613877/s   --  -2%
each 625568/s   2%   --

100:
         Rate loop each
loop  79481/s   -- -24%
each 104758/s  32%   --

1000:
        Rate loop each
loop  8140/s   -- -27%
each 11220/s  38%   --

10000:
       Rate loop each
loop  832/s   -- -26%
each 1124/s  35%   --

100000:
       Rate loop each
loop 81.6/s   -- -26%
each  110/s  34%   --

1000000:
       Rate loop each
loop 6.90/s   -- -26%
each 9.27/s  34%   --


With the three-part for loop, you are able to $i += 3 and such if you want from within the loop, but with the foreach loop, you are not. That is the difference.


The off-by-one error that you originally had in the C-style loop shows that the C-style loop is more error prone, and should only be used if you actually need access to the loop counter. A foreach loop makes it much more difficult to make an off-by-one error.


I believe that the two loop examples you posted behave identically. In both cases, $i is lexically scoped (since you use the my keyword). I think the 0..$n syntax is clearer, but (surprise!) not everyone would agree with that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜