Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Is for(@$array_ref) construct optimized? YES!

by Weasel (Sexton)
on Jun 16, 2002 at 18:16 UTC ( #174941=perlmeditation: print w/replies, xml ) Need Help??

Hello, all!

Many of us know that foreach (@array) {...} is optimized - no extra copying, just some iterations over array. But it was not obvious for me whether or not more complex constructs are optimized this way.
In such cases they better be written as: for ($i=0;$i<=$#array;$i++) {...}

So I wrote simple benchmark program and found out that optimizations which perl performs are quite good:

use strict; use Benchmark; my ($x,$i); my @f = ('a'..'zz'); my $f = \@f; sub first_one { for (@f) {$x++} } sub second_one { for (@$f) {$x++} } sub third_one { for ('a'..'zz') {$x++} } sub fourth_one { for ($i=0;$i<=$#f;$i++) {$x++} } timethese(10_000, { 'first' => \&first_one, 'second' => \&second_one, 'third' => \&third_one, 'fourth' => \&fourth_one, });
Benchmark: timing 10000 iterations of first, fourth, second, third... first: 6 wallclock secs ( 6.02 usr + 0.00 sys = 6.02 CPU) @ 16 +61.68/s (n=10000) fourth: 12 wallclock secs (11.98 usr + 0.00 sys = 11.98 CPU) @ 83 +4.86/s (n=10000) second: 7 wallclock secs ( 6.00 usr + 0.00 sys = 6.00 CPU) @ 16 +67.22/s (n=10000) third: 9 wallclock secs ( 9.57 usr + 0.00 sys = 9.57 CPU) @ 10 +44.50/s (n=10000)
So, I was here to share this knowledge.

Replies are listed 'Best First'.
Re: Is for(@$array_ref) construct optimized? YES!
by Aristotle (Chancellor) on Jun 16, 2002 at 19:38 UTC
    You're preaching to the converted. :) If you use -MO=Deparse, you'll see that the for(;;) gets compiled to a while with a continue block, the latter being where the massive performance difference weighs in. Considering that the for(@array) form eradicates fence post errors from the root, there's rarely any good reason to use for(;;) in Perl.

    Update: I forgot. Depending on your version of B::Deparse you may need increase the exposition level with the -x switch in order to see what things really look like to Perl under the hood.
    $ perl -MO=Deparse,-x7 -e 'for($i=0;$i<=10;$i++){}' $i = 0; while ($i <= 10) { (); } continue { ++$i } -e syntax OK $ perl -MB::Deparse -e' print "$B::Deparse::VERSION\n"' 0.6 $ perl -v This is perl, v5.6.1 built for i386-linux [...]

    Makeshifts last the longest.

      Sorry, I just checked a situation and can not confirm your sayings. Here is my log:
      D:\Work\PerlScripts\utl>perl -MO=Deparse -we "$x=[];for(@$x){}" $x = []; foreach $_ (@$x) { (); } -e syntax OK D:\Work\PerlScripts\utl>perl -MO=Deparse -we "$x=[];for(;;){}" Name "main::x" used only once: possible typo at -e line 1. $x = []; for (;;) { (); } -e syntax OK D:\Work\PerlScripts\utl>perl -MO=Deparse -we "$x=[];for($i=0;$i<=$#x;$ +i++){}" $x = []; for ($i = 0; $i <= $#x; ++$i) { (); } -e syntax OK
      This is probably version-dependent (which perl version you use?) and with less probablilty $^O-dependent (what is $^O in your case?)

      I think we'll find common denominator soon.

      update: after I saw your update I understood more and now I think we found that commond denominator that I've just mentioned. Thanks.

        On Linux with Perl5.6.0:
        $ perl -MO=Deparse -we '$x=[];for($i=0;$i<=$#x;$i++){}'
        $x = [];
        $i = 0;
        while ($i <= $#x) {
        continue {
        -e syntax OK
        Screamer is right - but thanks for preaching anyway, not all of us are 'converted' just yet. ;)


        (the triplet paradiddle with high-hat)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://174941]
Approved by cjf
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2020-02-23 05:07 GMT
Find Nodes?
    Voting Booth?
    What numbers are you going to focus on primarily in 2020?

    Results (102 votes). Check out past polls.