You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Paul <yd...@yahoo.com> on 2001/03/19 18:39:40 UTC

[OT]Re: my()speed (was: [DIGEST] mod_perl digest 03/17/01)

--- Geoffrey Young <gy...@laserlink.net> wrote:
>                           mod_perl digest
>                    March 11, 2001 - March 17, 2001
> Recent happenings in the mod_perl world...
> . . .
> mailing list highlights
> . . .
>   o There was an OT but interesting thread on whether lexical 
>     variables are faster than global variables [10].  This
>     response in particular may be of interest to those who
>     want to know more about perlguts [11]

As one more installment on that thread, I got an email using Benchmark
to test it. It had the my() inside the test function, which was slower
than package globals, but I moved it out and it was faster.

Here's the test synopsis:
===========================
C:\users\default>type tmp.pl
use Benchmark;
my $o;                       # packagewide deep-bound my() var
sub outMY{
    $o = 0;                  # packagewide deep-bound my() var
    $o++ while ($o < 1000);
};
sub inMY{
    my $i = 0;               # function-internal my() var
    $i++ while ($i < 1000);
};
sub gPK{
    $g = 0;                  # package global var
    $g++ while ($g < 1000);
};
timethese(5000, { 'External' => \&outMY,
                  'Internal' => \&inMY,
                  'Global'   => \&gPK    } );

C:\users\default>perl -w tmp.pl
Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  5 wallclock secs ( 4.96 usr +  0.00 sys =  4.96 CPU)
    Global:  5 wallclock secs ( 5.01 usr +  0.00 sys =  5.01 CPU)
  Internal:  4 wallclock secs ( 5.07 usr +  0.00 sys =  5.07 CPU)

===================================================================
Notice that a deep-bound my() variable was fastest, while a re-scoped
my() was slowest, the package global being pretty close to halfway
between in actual CPU usage.

Hope that's useful to somebody. =o)

Paul

__________________________________________________
Do You Yahoo!?
Get email at your own domain with Yahoo! Mail. 
http://personal.mail.yahoo.com/

Re: [OT]Re: my()speed (was: [DIGEST] mod_perl digest 03/17/01)

Posted by Stas Bekman <st...@stason.org>.
[the benchmark snipped]

> What can we conclude from all of this?  That Lexicals and globals run
> at (roughly) the same speed, and that tmtowtdi...

... but that doesn't mean that we should endorse using globals. This would
probably be different if globals were significantly faster. Fortunately
this is not the case...

_____________________________________________________________________
Stas Bekman              JAm_pH     --   Just Another mod_perl Hacker
http://stason.org/       mod_perl Guide  http://perl.apache.org/guide
mailto:stas@stason.org   http://apachetoday.com http://logilune.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/



Re: [OT]Re: my()speed (was: [DIGEST] mod_perl digest 03/17/01)

Posted by Robert Landrum <rl...@capitoladvantage.com>.
At 11:27 AM +0800 3/20/01, Stas Bekman wrote:
>On Mon, 19 Mar 2001, Paul wrote:
>
>>
>> --- Geoffrey Young <gy...@laserlink.net> wrote:
>> >                           mod_perl digest
>> >                    March 11, 2001 - March 17, 2001
>> > Recent happenings in the mod_perl world...
>> > . . .
>> > mailing list highlights
>> > . . .
>> >   o There was an OT but interesting thread on whether lexical
>> >     variables are faster than global variables [10].  This
>> >     response in particular may be of interest to those who
>> >     want to know more about perlguts [11]
>>
>> As one more installment on that thread, I got an email using Benchmark
>> to test it. It had the my() inside the test function, which was slower
>> than package globals, but I moved it out and it was faster.
>>
>> Here's the test synopsis:
>> ===========================
>> C:\users\default>type tmp.pl
> > use Benchmark;
>> my $o;                       # packagewide deep-bound my() var
>> sub outMY{
>>     $o = 0;                  # packagewide deep-bound my() var
>>     $o++ while ($o < 1000);
>> };
>> sub inMY{
>>     my $i = 0;               # function-internal my() var
>>     $i++ while ($i < 1000);
>> };
>> sub gPK{
>>     $g = 0;                  # package global var
>>     $g++ while ($g < 1000);
>> };
>> timethese(5000, { 'External' => \&outMY,
>>                   'Internal' => \&inMY,
> >                   'Global'   => \&gPK    } );
>>
>> C:\users\default>perl -w tmp.pl
>> Benchmark: timing 5000 iterations of External, Global, Internal...
>>   External:  5 wallclock secs ( 4.96 usr +  0.00 sys =  4.96 CPU)
>>     Global:  5 wallclock secs ( 5.01 usr +  0.00 sys =  5.01 CPU)
>>   Internal:  4 wallclock secs ( 5.07 usr +  0.00 sys =  5.07 CPU)
>>
>> ===================================================================
>> Notice that a deep-bound my() variable was fastest, while a re-scoped
>> my() was slowest, the package global being pretty close to halfway
>> between in actual CPU usage.
>>
>> Hope that's useful to somebody. =o)
>
>Unfortunately it's not very useful when the results are so close, unless
>you specify the platform, compiler args, which malloc version was used and
>much more. And others use the same or a similar setup.
>
>I've run the same benchmark on linux(k2.2.17), perl 5.6.1-PATCH2 and there
>are all the other details that I'm not telling here. But just to make a
>point, I get results with 'global' always being faster and
>external/internal giving relatively inconsistent results (see the
>variations on CPU cycles). For example, your code executed four times:
>
>[snip]


Normally, a stash in the average program contains hundreds of entries 
from different packages.  That must have some impact on the speed of 
the globals, right?

Well... I tested it (sort of) and created 1000 fake subs to populate 
the stash with extra entries.

for my $i (1..1000) {
	*{"x$i"} = sub {
		print $i."\n";
	};
}

Then continued to run the code above with the following results

Benchmark: timing 5000 iterations of External, Global, Internal...
   External:  3 wallclock secs ( 3.07 usr +  0.01 sys =  3.08 CPU) @
     Global:  3 wallclock secs ( 3.07 usr +  0.00 sys =  3.07 CPU) @
   Internal:  4 wallclock secs ( 3.10 usr +  0.00 sys =  3.10 CPU) @


Benchmark: timing 5000 iterations of External, Global, Internal...
   External:  9 wallclock secs ( 3.25 usr +  0.00 sys =  3.25 CPU) @
     Global:  6 wallclock secs ( 3.08 usr +  0.01 sys =  3.09 CPU) @
   Internal:  3 wallclock secs ( 3.10 usr +  0.00 sys =  3.10 CPU) @

Again, the globals were fastest, even with 1000 extra sybols in the stash.

And then I thought that perhaps the stash was ordered alphanumercally 
to improve performance.  So I renamed my 1000 subs with a "d$i" 
instead of the "x$i" and ran the test again, but I came up with the 
exact same numbers...

Then, I tried upping the number of symbols... first to 10000 then to 
100000 and ran again with the EXACT same times.

What can we conclude from all of this?  That Lexicals and globals run 
at (roughly) the same speed, and that tmtowtdi...

Rob

--
Warning: The contents of this message are made of bits which may or may not
be an accurate representation of my thoughts.

Re: [OT]Re: my()speed (was: [DIGEST] mod_perl digest 03/17/01)

Posted by Stas Bekman <st...@stason.org>.
On Mon, 19 Mar 2001, Paul wrote:

>
> --- Geoffrey Young <gy...@laserlink.net> wrote:
> >                           mod_perl digest
> >                    March 11, 2001 - March 17, 2001
> > Recent happenings in the mod_perl world...
> > . . .
> > mailing list highlights
> > . . .
> >   o There was an OT but interesting thread on whether lexical
> >     variables are faster than global variables [10].  This
> >     response in particular may be of interest to those who
> >     want to know more about perlguts [11]
>
> As one more installment on that thread, I got an email using Benchmark
> to test it. It had the my() inside the test function, which was slower
> than package globals, but I moved it out and it was faster.
>
> Here's the test synopsis:
> ===========================
> C:\users\default>type tmp.pl
> use Benchmark;
> my $o;                       # packagewide deep-bound my() var
> sub outMY{
>     $o = 0;                  # packagewide deep-bound my() var
>     $o++ while ($o < 1000);
> };
> sub inMY{
>     my $i = 0;               # function-internal my() var
>     $i++ while ($i < 1000);
> };
> sub gPK{
>     $g = 0;                  # package global var
>     $g++ while ($g < 1000);
> };
> timethese(5000, { 'External' => \&outMY,
>                   'Internal' => \&inMY,
>                   'Global'   => \&gPK    } );
>
> C:\users\default>perl -w tmp.pl
> Benchmark: timing 5000 iterations of External, Global, Internal...
>   External:  5 wallclock secs ( 4.96 usr +  0.00 sys =  4.96 CPU)
>     Global:  5 wallclock secs ( 5.01 usr +  0.00 sys =  5.01 CPU)
>   Internal:  4 wallclock secs ( 5.07 usr +  0.00 sys =  5.07 CPU)
>
> ===================================================================
> Notice that a deep-bound my() variable was fastest, while a re-scoped
> my() was slowest, the package global being pretty close to halfway
> between in actual CPU usage.
>
> Hope that's useful to somebody. =o)

Unfortunately it's not very useful when the results are so close, unless
you specify the platform, compiler args, which malloc version was used and
much more. And others use the same or a similar setup.

I've run the same benchmark on linux(k2.2.17), perl 5.6.1-PATCH2 and there
are all the other details that I'm not telling here. But just to make a
point, I get results with 'global' always being faster and
external/internal giving relatively inconsistent results (see the
variations on CPU cycles). For example, your code executed four times:

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  6 wallclock secs ( 5.57 usr +  0.64 sys =  6.21 CPU) @
    Global:  6 wallclock secs ( 5.14 usr +  0.60 sys =  5.74 CPU) @
  Internal:  7 wallclock secs ( 5.57 usr +  0.52 sys =  6.09 CPU) @

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  7 wallclock secs ( 5.52 usr +  0.63 sys =  6.15 CPU) @
    Global:  5 wallclock secs ( 5.01 usr +  0.44 sys =  5.45 CPU) @
  Internal:  6 wallclock secs ( 5.45 usr +  0.62 sys =  6.07 CPU) @

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  7 wallclock secs ( 5.54 usr +  0.56 sys =  6.10 CPU) @
    Global:  5 wallclock secs ( 5.08 usr +  0.43 sys =  5.51 CPU) @
  Internal:  7 wallclock secs ( 5.55 usr +  0.79 sys =  6.34 CPU) @

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  6 wallclock secs ( 5.65 usr +  0.53 sys =  6.18 CPU) @
    Global:  6 wallclock secs ( 5.18 usr +  0.50 sys =  5.68 CPU) @
  Internal:  7 wallclock secs ( 5.56 usr +  0.46 sys =  6.02 CPU) @

As you can see on my setup, Global is the fastest, and Internal comes next
in 3 out of 4 cases... Also I've the -DDEBUGGIN on, so may be that's what
makes the difference. So the standard 5.6.0 without debugging enabled
gives inconsistent results as well:

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  4 wallclock secs ( 3.13 usr +  0.54 sys =  3.67 CPU) @
    Global:  4 wallclock secs ( 3.21 usr +  0.28 sys =  3.49 CPU) @
  Internal:  3 wallclock secs ( 3.15 usr +  0.44 sys =  3.59 CPU) @

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  4 wallclock secs ( 3.09 usr +  0.15 sys =  3.24 CPU) @
    Global:  3 wallclock secs ( 3.19 usr +  0.51 sys =  3.70 CPU) @
  Internal:  3 wallclock secs ( 3.17 usr +  0.26 sys =  3.43 CPU) @

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  4 wallclock secs ( 3.10 usr +  0.35 sys =  3.45 CPU) @
    Global:  4 wallclock secs ( 3.23 usr +  0.33 sys =  3.56 CPU) @
  Internal:  4 wallclock secs ( 3.11 usr +  0.41 sys =  3.52 CPU) @

Benchmark: timing 5000 iterations of External, Global, Internal...
  External:  4 wallclock secs ( 3.17 usr +  0.29 sys =  3.46 CPU) @
    Global:  3 wallclock secs ( 3.15 usr +  0.38 sys =  3.53 CPU) @
  Internal:  4 wallclock secs ( 3.16 usr +  0.39 sys =  3.55 CPU) @

which gives no clue at all, which is the faster method to use. Though it's
almost twice faster with having -DDEBUGING off... :)

_____________________________________________________________________
Stas Bekman              JAm_pH     --   Just Another mod_perl Hacker
http://stason.org/       mod_perl Guide  http://perl.apache.org/guide
mailto:stas@stason.org   http://apachetoday.com http://eXtropia.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/