27

My current web application uses about 30 or so Contants (DEFINE()). I am reading things that variables are quicker. Provided that there is a naming convention to avoid variable overwrites, the only other draw back I see is that these variables would have to be defined as global variables some how in every function.

Which is faster? I use these constants a whole lot throughout my application and will probably be forever adding more to the list and they are used in and out of functions and classes.

David
  • 16,246
  • 34
  • 103
  • 162
  • 18
    "Premature optimization is the root of all evil". Tell me, if you can _measure_ any difference ;) – KingCrunch Oct 14 '11 at 10:43
  • 4
    The time saved is so slim it's not really worth any consideration. – Mikulas Dite Oct 14 '11 at 10:44
  • when would it be worth this optimisation? Is there a cost for each time you reference the constant? And is that more than when you reference a variable? these 30 constants are reference 100s on each page. – David Oct 14 '11 at 10:54
  • It looks like you're not using constants for what they are for. Must not be a problem, but I recommend them only to give some numbers a meaning like `define('SECONDS_PER_HOUR', 3600);` rather like to have configuration values (which I only assume you do, no offence please). The optimization would be more about speed to change your code (and make it testable) than execution speed. It's more likely that computers get faster faster then you will get into an execution speed bottleneck because of the issue you outline. – hakre Oct 14 '11 at 11:50
  • 2
    I'm rather sure that the difference wouldn't be "small" but rather nonexistent, seeing how PHP is an interpreted language, and either variables or constants need to be parsed, looked up, and their value fetched from RAM in the same way. It's not like there is an optimizing compiler (even though PHP does translate into some kind of bytecode) which could eleminate constant calculations at compile time. – Damon Oct 14 '11 at 22:34

6 Answers6

25

Constants defined using define() are fairly slow in PHP. People actually wrote extensions (like hidef) to improve the performance.

But unless you have loads of constants this shouldn't make much of a difference.

As of PHP 5.3 you can also use compile-time constants using const NAME = VALUE;. Those are much faster.

NikiC
  • 100,734
  • 37
  • 191
  • 225
  • 4
    What would your definiation of loads be? I have around 30 which are referenced 100s of times per page – David Oct 18 '11 at 12:04
  • 1
    @David 30 aren't much. Problems may only arise with hundreds of constants. – NikiC Oct 18 '11 at 15:40
13

The difference would be really small (micro optimizations). You would better encapsulate some of your constants in classes so you can access them by Classname::CONSTANT to not pollute the global namespace of your application.

str
  • 42,689
  • 17
  • 109
  • 127
8

A quick test showed that defining constants (define('FOO', 'bar');) is about 16 to 18 times slower than defining a variable ($foo = 'bar';), but using the defined (constant) value is about 4 to 6 times faster.

Aram
  • 348
  • 4
  • 10
4

I was benchmarking constants vs variables and noticed a significant improvement of performance when using variables over constants. I know it is pretty obvious but it is definietely worth taking into the cosideration that use of local variables over constants whenever possible.

If constants are being used inside loops number of times, it is definitely worth declaring the constant as a class / local variable and use it instead.

The benchmarking test case includes creating two functions. Each has a loop that executes 10000000 times. One access a constant declared in a constant file and one access a local variable.

TestConstants.php

class TestConstants 
{   
    const TEST_CONSTANT = 'This is a constant value';

}

Test.php

use TestConstants;

class Test {

    protected $TEST_CONSTANT;
    protected $limit = 10000000;
    function __construct() {
        $this->TEST_CONSTANT = 'This is a constant value';
    }

    function testA() {
        $limit = $this->limit;
        $time_start = microtime(true); 
        for ($i = 0; $i < $limit; ++$i) {
            TestConstants::TEST_CONSTANT;
        }
        $time_end = microtime(true);
        $execution_time = ($time_end - $time_start);
        echo ''. $execution_time .' seconds <br/>';
    }

    function testB() {
        $limit = $this->limit;
        $time_start = microtime(true); 
        for ($i = 0; $i < $limit; ++$i) {
            $this->TEST_CONSTANT;
        }
        $time_end = microtime(true);
        $execution_time = ($time_end - $time_start);
        echo ''. $execution_time .' seconds <br/>';
    }   
}

$test = new Test();
$test->testA();
$test->testB();

Results are as follows

testA() executes in 0.55921387672424 seconds

and

testB() executes in 0.33076691627502 seconds

PHP Version

5.6.30

I thought to share this as someone out there might be benefitted by avoiding direct calls to constants (especially inside loops) by declaring them as variables wherever applicable.

Thank you.

Anjana Silva
  • 8,353
  • 4
  • 51
  • 54
0

I recommend to put all of these values into the $_SESSION variable.
Then they are available to all routines in your application.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
Hank Lubin
  • 11
  • 2
0

I also can't imagine that any speed differential would be consequential. What is certainly true is that variables are much easier to use than are constants in many cases.

However it seems your real problem is that you have a bunch of configuration data and you want to avoid having to pass loads of variables to functions, or have to make them all global.

There is no one answer that works for everyone, but a popular solution is to either utilize a registry class or create one yourself. You can do this pretty easily by declaring a php array. Then you initialize the registry object, and your functions and classes access it through a static method call. Rather than provide you snippets, I'll just refer you to zend_config and zend_registry as examples. While ZF provides these, you should not be afraid to roll your own versions, as neither is particularly hard to recreate in a simpler form if you want to avoid the use of ZF in your project.

gview
  • 14,876
  • 3
  • 46
  • 51