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

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.


Replies are listed 'Best First'.
Re: Re: Re: Re: Re: infinite loop on while (@array)
by demerphq (Chancellor) on Mar 27, 2002 at 15:21 UTC
    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.

Re: Re: Re: Re: Re: infinite loop on while (@array)
by Juerd (Abbot) on Mar 27, 2002 at 15:16 UTC

    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.