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

嗯,不完全是这样,但这是一个例子.谁能解释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

解决方法:

Magic函数肯定比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

所以你有它.你可以清楚地看到魔术函数在使用时比公共方法执行大约多4倍.

**编辑**

现在,如果您动态创建新的class属性,魔术方法将仅在第一次调用,然后任何后续调用将访问动态创建的公共属性(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拱,内存,PHP版本等而有所不同.因此,这些结果不能被视为理所当然,而且一般来说,魔术方法的执行时间总是比使用声明的公共属性要长.或调用声明的公共方法.

**编辑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;
}

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

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...