Reputation: 26253
If I have the option of using a global variable or passing a variable, which option is better in terms of speed and memory usage?
// global variable
function func(){
global $var;
echo $var;
}
$var='string';
func();
// passing variable
function func($var){
echo $var;
}
$var='string';
func($var);
Upvotes: 2
Views: 2996
Reputation: 6854
Tl/dr: define const=const > parameter > global > $GLOBAL
However, the difference is really marginal, for 10 millions of operations, the difference is less than a second.
I ran the example of @Kevin Vaughan (I ran it 10'000'000 instead of 1'000'000) Windows 10 64bits, php 7.2 64bits
Pass value by parameter
Time: 0.62202191352844s
Memory: 0
Global var reference
Time: 0.70083403587341s
Memory: 0
GLOBALS array reference
Time: 0.84828305244446s
Memory: 0
GLOBALS array reference2
Time: 0.80545091629028s
Memory: 0
GLOBALS array const define
Time: 0.57029700279236s
Memory: 0
GLOBALS array const
Time: 0.57260584831238s
Memory: 0
The memory leak is gone, however, the difference of performance is really small. Yet, passing the values by parameter is still fast.
Updated code with new functions.
<?php
echo "<pre>";
$baseVar = str_repeat('x', 1000000);
$GLOBALS['myVar'] = $baseVar;
define('BASEVAR',$baseVar);
const BASEVAR2=BASEVAR;
function testfunc_param($paramVar) {
$localVar = $paramVar;
return $localVar;
}
function testfunc_global() {
global $myVar;
$localVar = $myVar;
return $localVar;
}
function testfunc_globalsarray() {
$localVar = $GLOBALS['myVar'];
return $localVar;
}
function testfunc_globalsarray2() {
return $GLOBALS['myVar'];
}
function testfunc_const() {
return BASEVAR;
}
function testfunc_const2() {
return BASEVAR2;
}
// Testing passing value by parameter
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
testfunc_param($baseVar);
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "Pass value by parameter\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
// Testing reference to global variable
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
testfunc_global();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "Global var reference\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
// Testing reference to global variable via $GLOBALS
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
testfunc_globalsarray();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "GLOBALS array reference\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
// Testing reference to global variable via $GLOBALS
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
testfunc_globalsarray2();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "GLOBALS array reference2\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
// Testing reference to global variable via $GLOBALS
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
testfunc_const();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "GLOBALS array const define\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
// Testing reference to global variable via $GLOBALS
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
testfunc_const2();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "GLOBALS array const\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
echo "</pre>";
Upvotes: 3
Reputation: 15220
TLDR: Pass by parameter
= $GLOBALS element
>>> global $var
When in doubt, test! The below results show that:
Results (see code further below):
Time is seconds elapsed, memory is memory potentially leaked.
$ php -e test.php
Pass value by parameter
Time: 0.20166087150574s
Memory: 0
Global var reference
Time: 70.613216876984s
Memory: 1048576
GLOBALS array reference
Time: 0.22573900222778s
Memory: 0
Test Code:
<?php
$baseVar = str_repeat('x', 1000000);
$GLOBALS['myVar'] = $baseVar;
function testfunc_param($paramVar) {
$localVar = $paramVar;
return $localVar;
}
function testfunc_global() {
global $myVar;
$localVar = $myVar;
return $localVar;
}
function testfunc_globalsarray() {
$localVar = $GLOBALS['myVar'];
return $localVar;
}
// Testing passing value by parameter
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
testfunc_param($baseVar);
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "Pass value by parameter\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
// Testing reference to global variable
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
testfunc_global();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "Global var reference\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
// Testing reference to global variable via $GLOBALS
memory_get_usage(); // in case this procs garbage collection
$memoryStart = memory_get_usage(true);
$timeStart = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
testfunc_globalsarray();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "GLOBALS array reference\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
Upvotes: 6
Reputation: 4511
In PHP, global $var
is essentially running $var = &$_GLOBALS['var']
behind the scenes, so you'd be looking at a search time of O(n)
. The cost in running the function with the variable passed in is so little that it's not worth optimizing against.
Generally, you should find a balance between what is functionally correct, what is easy to read / test, and what is fast. In this case, the speed difference is negligible, while the cost to overall readability and testability is pretty severe.
Upvotes: 2
Reputation: 1219
I don't think you would see any performance difference. But you should be aware it's not a good idea to use a global variable just for doing it. Eventually it would be a problem, for reading the code, developing and testing.
Upvotes: 1
Reputation: 9819
The global variable will probably be faster, but not in a way that it's detectable unless you microbenchmark it. So base your decisions on which code is more readable/maintainable (which will be passing the variable in almost all cases), not some speed advantage you'll normally never notice.
Upvotes: 3