gpt4 book ai didi

PHP Magic 比简单地设置类属性更快?

转载 作者:可可西里 更新时间:2023-11-01 00:37:15 27 4
gpt4 key购买 nike

嗯,不完全是这样,但这里有一个例子。谁能解释一下B和C的区别?使用魔术函数动态设置值而不是简单地在属性定义中设置值如何更快?

这是一些代码:

[root@vm-202-167-238-17 ~]# cat test.php; for d in A B C; do echo "------"; ./test.php $d; done;
#!/usr/bin/php
<?php

$className = $argv[1];

class A
{
public function __get($a)
{
return 5;
}
}

class B
{
public $a = 5;
}

class C
{
public function __get($a)
{
$this->a = 5;

return 5;
}
}

$a = new $className;

$start = microtime(true);

for ($i=0; $i < 1000000; $i++)
$b = $a->a;

$end = microtime(true);

echo (($end - $start) * 1000) ." msec\n";

------
598.90794754028 msec
------
205.48391342163 msec
------
189.7759437561 msec

最佳答案

魔术函数肯定比 PHP 中的任何其他函数都慢,应谨慎使用。这实际上是一个很好的博客主题(自动创建具有神奇功能的属性以加快速度......无论如何)。作为El Yobo声明,我修改了您的 PHP 脚本,以便测试更准确:

<?php

class A {
public function __get($a) {
return 5;
}
}

class B {
public $a = 5;
}

class C {
private $a = 5;
public function __get($a) {
return $this->a;
}
}

$classes = array('A','B','C');

header('Content-type: text/plain; charset=utf-8');
foreach ($classes as $className) {
$a = new $className;

$start = microtime(true);

for ($i=0; $i < 1000000; $i++) {
$b = $a->a;
}

$end = microtime(true);

echo 'Class ' . get_class($a) . ' = ' . (($end - $start) * 1000) ." msec\n";
}

导致

Class A = 378.85212898254 msec
Class B = 109.26413536072 msec
Class C = 423.51794242859 msec

所以,你有它。您可以清楚地看到,使用魔法函数时,其执行时间是公共(public)方法的大约 4 倍。

** 编辑 **

现在,如果您动态创建新的类属性,魔术方法只会在第一次调用,然后任何后续调用都将访问动态创建的public 属性(public 是为了向后兼容)。将 C 类更改为:

class C {
public function __get($a) {
$this->a = 5;
return 5;
}
}

会输出

Class A = 392.09413528442 msec
Class B = 110.16988754272 msec
Class C = 96.771955490112 msec

所以这就是为什么你会说:“嘿!它更快!”但是,看看我们是否将迭代次数从 1000000 减少到 10(例如):

Class A = 0.033140182495117 msec
Class B = 0.0078678131103516 msec
Class C = 0.01215934753418 msec

C 类现在比 B 慢,因为它是对魔术方法的初始调用。我最好的猜测是 PHP 处理动态创建的属性而不是声明的属性。但经过进一步研究,这些结果可能会因操作系统、CPU arch、内存、PHP 版本等而异。因此,这些结果不能想当然,而且一般来说,魔法方法总是需要更长的时间执行而不是使用声明的公共(public)属性或调用声明的公共(public)方法。

** 编辑 2 **

这里是 D 类测试,跳过了任何具有动态属性创建的魔术方法:

class D {
public function __construct() {
$this->a = 5;
}
}

1000 次迭代产生这些结果:

Class A = 1.3999938964844 msec
Class B = 0.42200088500977 msec
Class C = 0.3960132598877 msec
Class D = 0.37002563476562 msec <-- faster

让我们将迭代次数增加到大约 1'000'000:

Class A = 380.80310821533 msec
Class B = 109.7559928894 msec
Class C = 91.224908828735 msec <-- faster ???
Class D = 96.340894699097 msec

如果魔法方法有很大的开销成本,那么现在真正的问题是:为什么当重复很多次访问相同的属性时,是

public function __get($a) {
$this->a = 5;
return 5;
}

public function __construct() {
$this->a = 5;
}

在创建和访问动态属性时?

关于PHP Magic 比简单地设置类属性更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4496245/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com