在PHP中,define函数的效率如何?

20

C++ 预处理器中的 #define 与其他语言中的定义变量不同。

PHP 中的 define() 和创建一个变量有什么不同?

define("SETTING", 0);  
$something = SETTING;

vs

的翻译是

对比

$setting = 0;  
$something = $setting;

1
在PHP中要小心这种语言模式。在C++中,常量是“免费”的,因为所有逻辑都发生在编译时。在PHP中,它们的执行时间和内存使用方面都很昂贵,因为它发生在运行时。它们应该比在C++中更加节约地使用。$something = 0;在性能上等效于PHP(添加一个注释来描述该值)。不幸的是,这通常是最好的选择 - 这就是C++预处理器在幕后为您完成的工作。 - Abhi Beckert
10个回答

17

'define' 操作本身相当缓慢 —— 这一点已经得到了 xdebug 分析器的确认。

以下是来自 http://t3.dotgnu.info/blog/php/my-first-php-extension.html 的基准测试结果:

  • 纯粹的 'define'
    380.785 次每秒取值
    14.2647 毫秒/首个响应平均时间

  • 使用 'hidef' 扩展定义常量
    930.783 次每秒取值
    6.30279 毫秒/首个响应平均时间


链接失效更新

上面提到的博客文章已经从互联网上消失了。可以通过 Wayback Machine 查看。这里还有另一篇类似的文章

作者引用的库可以在 这里(apc_define_constants)这里(hidef 扩展) 找到。


5
php > $cat='';$f=microtime(1);$s='cowcow45';$i=9000;while ($i--){$cat.='plip'.$s.'cow';}echo microtime(1)-$f."\n";

0.00689506530762

php > $cat='';$f=microtime(1);define('s','cowcow45');$i=9000;while ($i--){$cat.='plip'.s.'cow';}echo microtime(1)-$f."\n";

0.00941896438599

这个结果可以重复出现并且结果相似。看起来常量的定义和/或使用比变量稍微慢一些。


5
一般来说,常量的概念是在你的程序中保持“恒定”的(听起来很有趣,对吧?;))。这意味着编译器(解释器)将在整个脚本中用FOOBAR的值替换"FOOBAR"。至于理论和优势,如果你编译,就这么多了。现在PHP非常动态,在大多数情况下,你不会注意到差异,因为每次运行都会编译PHP脚本。据我所知,除非你使用像APCZend OptimizereAccelerator这样的字节码缓存,否则你不应该看到常量和变量之间速度上的明显差异。然后它才有意义。所有其他关于常量的优点/缺点已经在PHP手册中提到并可找到。

4
以下是来自手册的不同之处:
  • 常量前面没有美元符号($);
  • 只能使用define()函数定义常量,而不能通过简单赋值来定义;
  • 可以在任何地方定义和访问常量,而不受变量作用域规则的限制;
  • 一旦设置了常量,就不能重新定义或未定义;
  • 常量只能评估为标量值。
对我来说,主要的好处是全局范围。 我肯定不会担心它们的效率 - 每当您需要一个不可更改的全局标量值时,请使用它们。

3
语法和作用域很明显,我的意思是性能方面。 - Prody

3

看起来效率不高。(我基于php.net上的一条评论做出所有假设,我还没有进行自己的基准测试。)

调用常量将比调用变量需要多2倍的时间。

检查常量的存在需要2毫秒,对于错误的判断需要12毫秒!

以下是来自php在线文档define页面评论中的基准测试:

在使用defined()之前,请查看以下基准测试:

true                                       0.65ms
$true                                      0.69ms (1)
$config['true']                            0.87ms
TRUE_CONST                                 1.28ms (2)
true                                       0.65ms
defined('TRUE_CONST')                      2.06ms (3)
defined('UNDEF_CONST')                    12.34ms (4)
isset($config['def_key'])                  0.91ms (5)
isset($config['undef_key'])                0.79ms
isset($empty_hash[$good_key])              0.78ms
isset($small_hash[$good_key])              0.86ms
isset($big_hash[$good_key])                0.89ms
isset($small_hash[$bad_key])               0.78ms
isset($big_hash[$bad_key])                 0.80ms

PHP版本为5.2.6,Apache 2.0,Windows XP。

每个语句执行1000次,虽然在1000个调用上的12ms开销不会让最终用户抓狂,但在与if(true)比较时,它确实显示出一些有趣的结果:

1)如果($true),几乎相同 2)如果(TRUE_CONST),几乎慢了一倍--我猜编译时没有进行替换(我必须再检查一下!)3)如果常量存在,则defined()慢了3倍4)如果常量不存在,则defined()慢了19倍5)无论你抛什么东西,isset()都非常高效(对于任何实现基于数组驱动事件系统的人来说是个好消息 - 比如我!)

可能要避免if(defined('DEBUG'))...

摘自tris+php@tfconsulting.com.au,2009年3月26日06:40

http://us.php.net/manual/en/function.defined.php#89886


1

定义是简单的静态概念,意味着它的值在运行时不能被更改,而变量是动态概念,因为您可以在过程中自由地操作其值。


0

当我运行速度测试时,设置并转储的常量比设置变量并转储它们要快一些。


0

2020更新(PHP 7.2,AMD Ryzen9,启用Zend OpCache)

总结:重新定义相同的常量会很慢。与$_GLOBALS比较和定义常量大约慢8倍,检查未定义的常量略慢。 不要使用全局变量。

  • 注意:自动加载器和require_once长路径很可能比defines问题更大。(require_once需要php stat(2)来检查符号链接中的每个目录,这可以通过使用文件的完整路径来减少,以便PHP加载器只需stat文件路径1次即可并且可以使用stat缓存)

代码:

$loops = 90000;
$m0 = microtime(true);
for ($i=0; $i<$loops; $i++) {
   define("FOO$i", true);
}
$m1 = microtime(true);
echo "Define new const {$loops}s: (" . ($m1-$m0) . ")\n";
// etc...

输出:

Define new const 90000s: (0.012847185134888)
Define same const 90000s: (0.89289903640747)
Define same super global 90000s: (0.0010528564453125)
Define new super global 90000s: (0.0080759525299072)
check same undefined 90000s: (0.0021710395812988)
check same defined 90000s: (0.00087404251098633)
check different defined 90000s: (0.0076708793640137)

-1

主要区别:

  • define 是常量,variable 是变量
  • 它们有不同的作用域/可见性

-3

不确定效率如何,但它比创建一个变量更好:

  • 它是一个常量:您无法重新定义或重新分配此 SETTING。
  • 如果找不到定义,则将 $something 设置为“SETTING”,这非常有用,例如在 i18n 中:如果缺少翻译(即相应的定义是本地化文件),我们会看到一个大写的单词,非常显眼...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接