in reply to Re: Re: infinite loop on while (@array)
in thread infinite loop on while (@array)

<pedant class="minor">

</pedant>

Yves / DeMerphq
---
Writing a good benchmark isnt as easy as it might look.

Replies are listed 'Best First'.
Re: Re: Re: Re: infinite loop on while (@array)
by Kanji (Parson) on Mar 27, 2002 at 14:33 UTC

    Using B::Deparse under ActivePerl b629 (aka 5.6.1)...

    C:\> perl -MO=Deparse -e "while (1) { print 1; }" for (;;) { print 1; } -e syntax OK C:\> perl -MO=Deparse -e "for (;;) { print 1; }" for (;;) { print 1; } -e syntax OK

    But if I try the for example that demerphq quotes under Perl 5.5.3 (on FreeBSD), I get ...

    $ perl -MO=Deparse -le 'for ( my $i = 0; $i < 10; $i++ ) { print 1 }' -e syntax OK my $i = 0; while ($i < 10) { print 1 } continue { ++$i }

    Hmmm...

        --k.


      Actually this means nothing. (Sorry ;-) The issue is still open...
      D:\Development> perl -MO=Deparse,-x3 -e "for ($i = 0; $i < 10; ++$i) { +print $i;}" $i = 0; while ($i < 10) { print $i; } continue { ++$i } -e syntax OK
      From B::Deparses documentation <super>(Emphasis by me)</super>:
      -xLEVEL
      Expand conventional syntax constructions into equivalent ones that expose their internal operation. LEVEL should be a digit, with higher values meaning more expansion. As with -q, this actually involves turning off special cases in B::Deparse's normal operations. If LEVEL is at least 3, for loops will be translated into equivalent while loops with continue blocks; for instance
      for ($i = 0; $i < 10; ++$i) { print $i; }
      turns into
      $i = 0; while ($i < 10) { print $i; } continue { ++$i }
      Note that in a few cases this translation can't be perfectly carried back into the source code -- if the loop's initializer declares a my variable, for instance, it won't have the correct scope outside of the loop.
      In fact if anything I would say that Deparse suggests that in fact for(;;) is converted into while{}continue{} not the other way around. Although the trailing paragraph that I quoted suggests that its not quite so straightforward as perhaps we might like...

      :-)

      Yves / DeMerphq
      ---
      Writing a good benchmark isnt as easy as it might look.

      But if I try the for example that demerphq quotes under Perl 5.5.3 (on FreeBSD), I get ...

      for (;;) ne for (EXPR; EXPR; EXPR). The expressionless C-style for is special: it's an infinite loop. while (1) would be very inefficient, because it would have to check an expression on every iteration. Perl is smart, and knows what you're doing, and optimizes as follows:

      2;0 juerd@ouranos:/root$ perl -MO=Deparse -e'while (1) { print }' for (;;) { print $_; } -e syntax OK
      You see? it's converted to for (;;) because it's more effecient. We can't benchmark the difference because of this optimization...

      U28geW91IGNhbiBhbGwgcm90MTMgY
      W5kIHBhY2soKS4gQnV0IGRvIHlvdS
      ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
      geW91IHNlZSBpdD8gIC0tIEp1ZXJk
      

        You see? it's converted to for (;;) because it's more effecient. We can't benchmark the difference because of this optimization...

        Hmm, im sorry but this is inconclusive to me. The output of B::Deparse is not necessarily exactly what is happening under the hood (as I said to kanji above). Now you may be correct that perl optimizes for(;;) and while(1) into the same construct, but nothing ive seen posted here shows what that construct is.

        BTW a benchmark of while(1) versus for(;;) is as follows:

        Benchmark: timing 1000000 iterations of for(;;), while(1)... for(;;): 71 wallclock secs (71.66 usr + 0.00 sys = 71.66 CPU) @ 13 +955.57/s (n=1000000) while(1): 71 wallclock secs (71.67 usr + 0.00 sys = 71.67 CPU) @ 13 +952.45/s (n=1000000) Rate while(1) for(;;) while(1) 13952/s -- -0% for(;;) 13956/s 0% --
        I agree this suggests they optimize down to the same thing..

        :-)

        Yves / DeMerphq
        ---
        Writing a good benchmark isnt as easy as it might look.