SPUG: Using subroutines to return constants
Brian Ingerson
briani at activestate.com
Sat Nov 4 14:38:55 CST 2000
Richard Anderson wrote:
>
> Subtitle: Structured coding best practice or performance-crippling hack?
>
> Although Perl 5.6 has the convenient constant declaration to fix the value
"use constant" preceeds 5.6. I assume that was the convenience that you
meant.
> of a variable, most of us are still coding without this bit of syntactic
> sugar. The traditional way to refer to a constant in Perl is to use a
> reference to a subroutine that does nothing but return the constant:
>
> $PI = sub { 3.1415962 };
Not the tradition I'm familiar with. I think the traditional idiom is:
sub PI { 3.1415926 }
Then you can say:
my $area = PI * $r ** 2;
Your way, you'd say:
my $area = &$PI $r ** 2;
You might as well just defined it as:
my $PI = 3.1415926;
>
> I get a performance slowdown factor of 7 for the subroutine call on both
> Windows and Linux. Pretty nasty hit just to make your code cleaner.
>
> Any thoughts on this?
Yes. Perl will "inline" any sub that is prototyped and evaluates to a
constant. So using this:
sub PI () { 3.1415926 }
will effectively replace all references to PI with the constant. "use
constant" does the same thing. A good explanation of this is in the new
Camel p228.
Running this:
----------------8<----------------------------
my $PI_1 = sub { 3.1415962 };
sub PI_2 { 3.1415962 };
sub PI_3 () { 3.1415962 };
use constant PI_4 => 3.1415962;
my $PI_5 = 3.1415962;
use Benchmark;
my $r = 7;
timethese(10_000_000,
{
subref => sub {&$PI_1 * $r ** 2},
sub => sub { &PI_2 * $r ** 2},
inline => sub { PI_3 * $r ** 2},
constant => sub { PI_4 * $r ** 2},
scalar => sub { $PI_5 * $r ** 2},
}
);
----------------8<----------------------------
produces:
Benchmark: timing 10000000 iterations of constant, inline, scalar, sub,
subref...
constant: 13 wallclock secs (13.88 usr + 0.00 sys = 13.88 CPU)
inline: 14 wallclock secs (13.73 usr + 0.02 sys = 13.75 CPU)
scalar: 14 wallclock secs (13.58 usr + 0.00 sys = 13.58 CPU)
sub: 25 wallclock secs (24.37 usr + 0.00 sys = 24.37 CPU)
subref: 25 wallclock secs (24.76 usr + 0.00 sys = 24.76 CPU)
Just say "use constant"
Brian
--
perl -e 'use Inline C=>q{SV*JAxH(char*x){return newSVpvf
("Just Another %s Hacker\\n",x);}};print JAxH+Perl'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Subscriptions; Email to majordomo at pm.org: ACTION LIST EMAIL
Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
For daily traffic, use spug-list for LIST ; for weekly, spug-list-digest
Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/
More information about the spug-list
mailing list