简体   繁体   English

PHP:为什么`global`的使用比在函数内部声明变量要慢?

[英]PHP: Why is the use of `global` slower than declaring a variable inside a function?

I have been reading PHP manual pages, but I am obviously reading the wrong ones. 我一直在阅读PHP手册页,但显然我读错了。 I ran a few simple tests to see which means of obtaining a variable was faster: using global , declaring the variable inside the function, or using a declared constant. 我进行了一些简单的测试,以了解获得变量的更快方法:使用global ,在函数内部声明变量或使用声明的常量。

Summary: 摘要:

  1. Declaring the variable (eg, $keyspace = 012...; ) was fastest. 声明变量(例如$keyspace = 012...; )最快。
  2. Using global (eg, global $keyspace; ). 使用global (例如, global $keyspace; )。
  3. Defining a constant (eg, define('keyspace', '01234...'); was slowest. 定义常量(例如define('keyspace', '01234...'); )最慢。

Question: Why is using global or define slower than declaring a variable in PHP? 问题:为什么使用globaldefine比在PHP中声明变量要慢?

(1) Variable defined outside function, function uses global (1)外部函数定义变量,函数使用global

$keyspace = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
function buildSKU(){
        global $keyspace;
        $sku = '';
        $max = mb_strlen($keyspace, '8bit') - 1;
        for ($i = 0; $i < 8; ++$i) {
                $sku .= $keyspace[random_int(0, $max)];
        }
        return $sku;
}

(2) Variable defined inside function (2)在函数内部定义的变量

function buildSKU(){
        $keyspace = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $sku = '';
        $max = mb_strlen($keyspace, '8bit') - 1;
        for ($i = 0; $i < 8; ++$i) {
                $sku .= $keyspace[random_int(0, $max)];
        }
        return $sku;
}

(3) Variable defined as a constant (3)定义为常数的变量

define('keyspace', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ');
function buildSKU(){
        $sku = '';
        $max = mb_strlen(keyspace, '8bit') - 1;
        for ($i = 0; $i < 8; ++$i) {
                $sku .= keyspace[random_int(0, $max)];
        }
        return $sku;
}

My test bed: 我的测试床:

<?php

$start = microtime(true);
//Put (1) or (2) here...
for($i=0; $i<10000; $i++){ buildSKU(); }
$end = microtime(true) - $start;
echo "\n\nTime: ".$end."\nMemory:".memory_get_peak_usage(true)."\n\n";

Your title is a bit misleading. 您的标题有点误导。 A function variable is not being 'declared' over and over, it was declared once when you wrote the function code. 不会一遍又一遍地“声明”一个函数变量,而是在编写函数代码时声明一次。 You also focused on an apples to oranges comparison. 您还专注于苹果与桔子的比较。

With the function variable example, the scope of the variable is entirely different. 对于函数变量示例,变量的范围完全不同。 A local variable declared inside a function ceases to exist (at least from the scope perspective) once the function completes. 一旦函数完成,在函数内部声明的局部变量将不复存在(至少从作用域角度而言)。 It's also being initialized, unlike the global example where the state of the variable at the start of the function is completely unknown. 它也正在初始化,这与全局示例不同,在全局示例中,函数开始时变量的状态是完全未知的。

You spent a lot of time looking at micro optimization and a meaningless benchmark, when the answer is much simpler. 当答案要简单得多时,您花费了大量时间在微优化和毫无意义的基准上。 It is never better to use the global keyword to inject a variable into function scope. 最好不要使用global关键字将变量注入函数范围。

You have parameters for doing that which can be passed by reference or value, but you did not evaluate those options, although I have to reiterate that in my opinion you aren't really going to find out anything interesting. 您具有可以通过引用或值传递的参数,但是您没有评估这些选项,尽管我不得不重申,我认为您实际上并不会发现任何有趣的东西。

In most languages that create a compiled program, function variables are allocated on the stack. 在大多数创建已编译程序的语言中,函数变量都分配在堆栈上。 Once the function completes, that area of memory is popped off the stack and discarded. 功能完成后,该内存区域将从堆栈中弹出并丢弃。 PHP however, has aa variable naming and memory allocation scheme that is shared across all variables and objects. 但是,PHP具有一个变量命名和内存分配方案,该方案在所有变量和对象之间共享。 You can search for information on 'php zval' and php internals, and find out more about the way variables are allocated, reference counted, and associated with names via symbol tables. 您可以搜索有关“ php zval”和php内部信息的信息,并通过符号表找到有关变量分配,引用计数以及与名称关联的方式的更多信息。

The important point to make here, is that the variable allocation occurs in the same way regardless of the type of variable it is, so any expectation about performance purely of variable allocation syntax is unlikely to provide any meaningful differences. 这里要说明的重要一点是,无论变量的类型是什么,变量分配都以相同的方式发生,因此,仅对变量分配语法的性能提出的任何期望都不太可能提供任何有意义的差异。

PHP makes all sorts of decisions in regards to when it needs to make a new zval or simply point multiple symbols at the same one, and that is meant to be transparent to you. PHP就何时需要制作一个新的zval或只是将多个符号指向同一符号做出各种决定,这对您来说是透明的。

I think the main issue with global is the dependency issue, where your entire code base would be depended on that global variable and its existence, as your code grows , it is very hard to keep track and trouble shoot. 我认为global的主要问题是依赖关系问题,其中整个代码库都将依赖于该全局变量及其存在,因为随着代码的增长,很难跟踪和排除故障。 Even a name change requires you change everywhere in your code. 即使是名称更改,也要求您在代码中的所有位置进行更改。

in your code if key doesn't change maybe you should consider using constant. 在代码中,如果键不变,那么您应该考虑使用常量。

除非绝对需要,否则请始终使用局部变量,并且别无选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM