The best way to access PHP global variable
I have been playing with PHP minor optimization for a while, but this is the first time I go for it seriously. My question for today is what's the best way to work with PHP global variables and how to achieve best performance for it. Rumours say that global keyword is slow, so this is a good time to check it out. And I also want to check if the number of variables affects the performance of the method.
Setup
The first thing todo is to define how we can access a global variable. The below is the list of ways to access global method that I use for the performance testing.
1. Use global keyword
It can't be simpler.
global $value;
2. Access $GLOBALS array
Instead of using the global keyword. I will access the global array directly.
$GLOBALS['value'];
3. Access $GLOBALS array with reference
Like the above method, but using reference. This way may be faster because we don't have to access the global array again and again.
$value =& $GLOBAL['value'];
4. Access $GLOBALS array and assign the value later
In this method, I fetch the value first, doing stuff with this and assign it to the global scope again. The code below illustrate the idea of this method.
$value = $GLOBAL['value']; // doing stuff $GLOBAL['value'] = $value;
5. Using a global array
Instead of using global variables in global scope. I store all global variables in an array and access it later. This method is useful because it reduces variable conflictment when the application grows.
global $ARR; $ARR['value'];
6. Using a global object
Like the above method, but use an object to store the variable.
global $OBJ; $obj->value;
7. Static class variable
I use a class to manage static variable. Many modern developers use this way to store global variable and configuration.
class GLB { public static $vars; } GLB::$vars['value'];
8. Static function variable - reference return
This is a another way to store / retrive global variables. I want to compare it with other method to see how it's different to others.
function &globalzie($name) { static $vars = array(); return $vars[$name]; } $value =& globalzie('value');
9. Static function variable - reference parameter
The same approach, but different way to retrive the variable. I don't like the reference assign operator on the above method.
function globalize($name,&$var) { static $vars = array(); $var =& $vars[$name]; } globalzie('value',$value);
Running the test
I then ran the tests under my laptop with the following configuration: Acer Aspire 5920G, Windows 7 Pro, 1.8 T7100, 3GB Ram, PHP 5.2.9 and Apache 2.0.2. A test is one of the functions above, access the variable(s) and then increase to 100. Each test is run many times to stimulate the traffic of the application (here I run each test for 100, 1000, 10000 and 100000 times). I also tested with different variable number, to see if the number of variables affect the performance or not. An example of test function will look like:
function t1() { global $a1,$a2,$a3,$a4; for ($i = 0;$i < 100;$i++) { $a1++; $a2++; $a3++; $a4++; } }
You can find the spreadsheet and benchmark code under attachment section.
Analyze the result
The first thing we can see is using a static class (#7) to store global variable is always far behind from other methods. Using a global object (#6) is always slower than using an other global array (#5) to store global variables. So when it comes to OOP, it's always slower. The second thing we can see is using $GLOBALS directly (#2) is always slower than other method. That's can be explained because of heavy array access and update. But there's something new is using a global variable to store global variables (#5 & #6) is actually always faster than using $GLOBALS. So it's best to avoid using $GLOBALS directly.
Compare #3 and #4, we can see that it's faster to use reference. So we can discard the #4 method. It's strange for me to see that #8 is actually faster than #9 most of the time (there's sometime #9 is faster, but only for a very few times). Maybe the extra reference parameter. Through using static function variable is faster than an-other-global variable, it's still slower than using global keyword (#1) and $GLOBALS reference . So the final candidate is #1 and #3. Now it comes to the fun part. #1 and #3 give nearly the same result for most of the tests. Sometime, #1 is faster, sometime #3 is faster. And if we stick to the performance sheet, I will say that #3 gives more best result than #1 so using global keyword is slower than reference to the $GLOBALS variable. But we can see the distance is not so faraway, so #1 and #3 is nearly the same but it's sure that we prefer #1 to #3 because of syntax.
Conclusion
When you use a global variable, do not invent new method to store global variable , just use what PHP provides you. It will serve the best performance. And remember, OOP is very very slow. But in case you want to implement something like lazy global variable initialization then try to implement it in a function (#8 or #9), a function call is cheaper than a static method call.
I hope this article is useful for you, and if you find some mistake please help me to correct it
.
Post new comment