On Tue, May 12, 2009 at 18:11, John W. Krahn <jwkr...@shaw.ca> wrote:
> Bryan Harris wrote:
>>
>> [stuff cut out]
>>
>>> It is usually best to declare variables in the smallest scope possible
>>> so:
>>>
>>> while (more work to do)
>>> {
>>>  my @array = split $string;
>>>
>>>  # do work on array
>>> }
>>>
>>
>> Doesn't that try to re-localize (?) the @array variable every time through
>> the loop?  i.e. doesn't it re-run the my() function every time through the
>> loop?  For some reason I thought that was a no-no.
>
> my() happens when the code is compiled so it is *not* re-run every time
> through the loop.  The assignment happens when the code is run so it is
> re-run every time.
snip

That depends on what you mean by "run".  A new variable is created
each time through the loop and it is assigned a value.  You can prove
this by saying

#!/usr/bin/perl

use strict;
use warnings;

use Scalar::Util qw/refaddr/;

my ($once, @once, @many);
for my $i (1 .. 3) {
        my $many = $i;
        $once    = $i;
        push @once, \$once;
        push @many, \$many;
        print "once ", refaddr \$once, " many ", refaddr \$many, "\n";
}
print "once: ", (map { "$$_ " } @once), " many ", (map {"$$_ "} @many), "\n";

This is not as efficient as declaring it once before the loop and
reusing it, but it is much safer and what you should do unless you can
prove that the inefficiency is costing you real time (premature
optimization is the root of all evil[1]).

once => 55
many => 55

for a loop of 10 items:
         Rate many once
many 293287/s   --  -7%
once 317010/s   8%   --

for a loop of 100 items:
        Rate many once
many 38495/s   -- -15%
once 45522/s  18%   --

for a loop of 1000 items:
       Rate many once
many 3980/s   -- -18%
once 4867/s  22%   --

for a loop of 10000 items:
      Rate many once
many 399/s   -- -19%
once 492/s  23%   --


#!/usr/bin/perl

use strict;
use warnings;

use Benchmark;

my $n = 10;
my %subs = (
        once => sub {
                my $once;
                my $sum;
                for my $i (1 .. $n) {
                        $once = $i;
                        $sum += $once;
                }
                return $sum;
        },
        many => sub {
                my $sum;
                for my $i (1 .. $n) {
                        my $many = $i;
                        $sum += $many;
                }
                return $sum;
        }
);

for my $sub (keys %subs) {
        print "$sub => ", $subs{$sub}(), "\n";
}

for my $i (10, 100, 1_000, 10_000) {
        $n = $i;
        print "\nfor a loop of $n items:\n";
        Benchmark::cmpthese -5, \%subs;
}

1. http://portal.acm.org/citation.cfm?id=356640

-- 
Chas. Owens
wonkden.net
The most important skill a programmer can have is the ability to read.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to