PHP中的全局变量还是传递变量?(表演)

PHP中的全局变量还是传递变量?(表演),php,Php,如果我可以选择使用全局变量或传递变量,在速度和内存使用方面,哪个选项更好 // global variable function func(){ global $var; echo $var; } $var='string'; func(); // passing variable function func($var){ echo $var; } $var='string'; func($var); 全局变量可能会更快,但除非你对其进行微基准标记,否则无法检测到。因此,您

如果我可以选择使用全局变量或传递变量,在速度和内存使用方面,哪个选项更好

// global variable
function func(){
  global $var;
  echo $var;
}

$var='string';
func();


// passing variable
function func($var){
  echo $var;
}

$var='string';
func($var);

全局变量可能会更快,但除非你对其进行微基准标记,否则无法检测到。因此,您的决策基于哪些代码更可读/更可维护(几乎在所有情况下都会传递变量),而不是您通常不会注意到的速度优势。

我认为您不会看到任何性能差异。但是您应该意识到,仅仅使用全局变量并不是一个好主意。在PHP中,
global$var
基本上是在后台运行的
$var=&$\u GLOBALS['var']
,因此您将看到的搜索时间是
O(n)
。使用传入的变量运行函数的成本非常低,因此不值得对其进行优化


通常,您应该在功能正确、易于阅读/测试和快速之间找到平衡。在这种情况下,速度差异可以忽略不计,而总体可读性和可测试性的成本相当高。

TLDR:
=
$GLOBALS-element
>
global$var

如果有疑问,请测试!以下结果表明:

  • 通过参数传递1Mb字符串要比通过全局$var传递ref性能好得多
  • 通过参数传递1Mb字符串的性能与使用$GLOBALS['var']的性能大致相同
  • 以下面的方式使用global$var似乎会弄乱内存上的GC引用计数,速度慢得可笑。显然,对于这种虚构的案例,不要使用全局$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";
    
    
    Tl/dr:定义常数=常数>参数>全局>全局$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>";
    

    我认为这不会有多大区别,代码的可读性很重要。即使传递变量稍微慢一点(我不知道是否慢一点),您通常还是应该避免使用全局变量。使用PHP7.0。谢谢,真的。这些结果来自2014年。有关使用现代php版本的更新,请参见上面的@magallanes answer。@KevinVaughan Boop。