如果我可以选择使用全局变量或传递变量,哪个选项在速度和内存使用方面更好?
// global variable
function func(){
global $var;
echo $var;
}
$var='string';
func();
// passing variable
function func($var){
echo $var;
}
$var='string';
func($var);
答案 0 :(得分:4)
TLDR: Pass by parameter
= $GLOBALS element
>>> global $var
如有疑问,请测试!以下结果表明:
结果(请参阅下面的代码):
时间是经过几秒钟,内存可能是内存泄漏。
$ 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
测试代码:
<?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";
答案 1 :(得分:3)
全局变量可能会更快,但除非你对它进行微基准测试,否则它不会被检测到。因此,决定哪些代码更易读/可维护(几乎在所有情况下都会传递变量),而不是通常从未注意到的速度优势。
答案 2 :(得分:1)
我认为你不会看到任何性能差异。但是你应该意识到使用全局变量并不是一个好主意。最终,阅读代码,开发和测试将是一个问题。
答案 3 :(得分:1)
在PHP中,global $var
基本上在幕后运行$var = &$_GLOBALS['var']
,因此您需要查看O(n)
的搜索时间。使用传入的变量运行函数的成本非常低,以至于不值得优化。
通常,您应该在功能正确,易于阅读/测试和快速之间找到平衡点。在这种情况下,速度差异可以忽略不计,而整体可读性和可测试性的成本非常高。
答案 4 :(得分:0)
Tl / dr:定义const = const>参数>全局> $ GLOBAL
但是,差异确实很小,对于1000万次操作,差异不到一秒钟。
我运行了@Kevin Vaughan的示例(我运行了10'000'000而不是1'000'000)Windows 10 64位,php 7.2 64位
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
内存泄漏消失了,但是,性能差异确实很小。但是,通过参数传递值仍然很快。
具有新功能的更新代码。
<?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_const();
}
$timeEnd = microtime(true);
$memoryEnd = memory_get_usage(true);
print "GLOBALS array const\nTime: ".($timeEnd - $timeStart)."s\nMemory: ".($memoryEnd-$memoryStart)."\n\n";
echo "</pre>";