saurabh.hirani has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys,

I am writing a program which is going to create an object of a perl class and uses a bunch of constants. I don't want to export those constants because I can access them through my class object. I was going through the constant man page and saw that perl replaces constant values by their inline subroutine calls.


My question is: Is using constants slower than using variables? If yes, is there a better way to use constants?

I am asking this because my program is going to be a sendmail milter (a program which is called for each stage of an SMTP session to decide whether the message is acceptable depending on sender, rcpt, etc). It is going to be bombed with SMTP transactions at a very high rate.


A sample snippet of code:

my $logobj = new Merce::Log; $logobj->log($logobj->PRIORITY, $logobj->MSGTMPL);

I have seen guys using $:: for constants or exporting them but I don't want to do that. You might think I am doing premature optimization but I was curious to know.

Replies are listed 'Best First'.
Re: The best way to use constants
by almut (Canon) on Apr 02, 2009 at 16:33 UTC
    Is using constants slower than using variables?

    In case of doubt, I would just Benchmark it...

Re: The best way to use constants
by perrin (Chancellor) on Apr 02, 2009 at 16:44 UTC
    Common wisdom is that in-lined subroutines aka 'use constant' are very slightly faster than variables. However, you're accessing them as class methods, which probably makes them worse. Either way, I would suggest you avoid them because they lead to subtle programming errors and are simply not worth it. If you really can't be talked out of it, you probably have to export them to get the minimal speed gains.
Re: The best way to use constants
by pileofrogs (Priest) on Apr 02, 2009 at 16:46 UTC

    From the man page for constant:

    In the current implementation, scalar constants are actually inlinable subroutines. As of version 5.004 of Perl, the appropriate scalar con- stant is inserted directly in place of some subroutine calls, thereby saving the overhead of a subroutine call. See "Constant Functions" in perlsub for details about how and when this happens.

    From perlsub

    If the result after optimization and constant folding is either a constant or a lexically-scoped scalar which has no other references, then it will be used in place of function calls

    So, I'd interpret this to mean your constant really will be treated as you'd expect and like if it's really really a constant. Read up Constant Functions in perlsub for a better explaination.

Re: The best way to use constants
by JavaFan (Canon) on Apr 02, 2009 at 18:26 UTC
    Is using constants slower than using variables
    Considering that Perl doesn't have constants, the question isn't clear. It will depend on what you consider a constant. Many people consider a variable in all caps to be a constant. That of course is as fast as using constants.

    Others use "use constant" or tiny subs with an empty prototype returning a literal as constants. Are they faster than variables? Well, that depends. If it's just fetching a value (read access), yes, then they are faster as the fetch can be done at compile time. But such constants lack a sigil. So you cannot easily interpolate them. Hence, you might write:

    printf "The value is %d.\n", CONSTANT;
    instead of
    print "The value is $CONSTANT.\n";
    The former means parsing a format, and substituting. That may very well be slower than the interpolation.

    Now, you are using methods as constants. I haven't benchmarked it, but I'd be quite surprised if that wasn't the slowest solution of the three (variable, empty prototype sub, method).

    Personally, I prefer variable. In all caps. Speed difference isn't an issue for me. Variables interpolate; subs and methods don't. If I want to trap a possible assignment to such a variable, I use Readonly. But usually, I do not care. If someone wants to assign to something that's supposed to constant, it's their own responsibility. Who am I to stop them?

      If I want to trap a possible assignment to such a variable, I use Readonly.

      This comparison of Readonly against some alternatives (like Scalar::Readonly) might be of interest here.

        Thanks a lot guys for your viewpoints. Scalar::Readonly looks interesting and so does the idea of not using class methods and exporting the constants.