PHP - 变量变量的替代品

时间:2015-10-20 17:25:20

标签: php performance variables

假设我有一个对象$foo,我在字符串变量$bar中有一个参数的名称。

我知道我可以使用$foo->$bar访问参数的值,但我听说这在性能方面有点糟糕。

因此我的问题是:有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

首先,我应该说我同意这篇文章其他地方的观点,认为它可能不是一种值得花时间的优化。但是,我喜欢它,因为它促进了好奇心。为了满足这种好奇心,我编写了一个小型基准测试程序,将$foo->$bar与第一个想到的替代方案进行比较:$foo->someKnownArrayProperty[$bar]。事实证明,第一个一直是快10%左右。我在1M次迭代中测试了几次运行,然后在10M时测试了几次。这是我非常基本的代码:

<?php
$iterations = 10000000;
$bar = 'someproperty';
class Foo {

}
$foo = new Foo();
$start = microtime(TRUE);
for($i = 0; $i<$iterations; $i++) {
  $rand = rand(1,1000);
  $foo->$bar = $rand;
  if($foo->$bar != $rand) {
    throw new Exception("A problem occurred reading or writing $bar");
  }
}
$end = microtime(TRUE);
$varproptime = $end - $start;
unset($foo);
$foo = new Foo();
$start = microtime(TRUE);

$foo->myarray = array();
for($i = 0; $i<$iterations; $i++) {
  $rand = rand(1,1000);
  $foo->myarray[$bar] = $rand;
  if($foo->myarray[$bar] != $rand) {
    throw new Exception("A problem occurred reading or writing $bar");
  }
}
$end = microtime(TRUE);
$arrayproptime = $end - $start;
printf("Variable Property: %f.4\nArray Property: %f.4\n", $varproptime, $arrayproptime);

一般来说,1M迭代时间为1.0秒和1.1秒,10M时间为10秒和11秒。

修改

我进一步提出了另一个想法:我们可以编译&#39;一个有“本地人”的班级。财产,以及一个二传手和一个吸气。这只是我头脑中的另一个想法。事实证明,这对于性能来说是可怕的,因为我们需要在堆栈中添加一个帧(使用setter和getter而不是直接访问)。我需要添加它们的原因是,如果这个想法是允许所有代码是静态的,那么目标就是&#39;一旦迭代开始。基本上我通过eval()运行了一个类定义,它应该使程序处于一个等价的状态,如果它是用属性名称硬编码的。例如,如果您在编程时不知道属性名称,那么这个想法将是有价值的,但是在请求时它只是一个值并且可以读取/写入很多次。我想也许更长一段时间的启动&#39;如果时间导致更快的访问模式,则可以抵消时间。但它没有。这大约慢了100%。

$classDefinition = <<<EOD
class FOO {
  public \$$bar;
  function setThatThing(\$value) {
    \$this->$bar = \$value;
  }
  function getThatThing() {
    return \$this->$bar;
  }
EOD;
eval($classDefinition);

在执行时,看起来像这样(注意一些$被转义,有些没有)

class FOO {
  public $someproperty;
  public function setThatThing($value) {
    $this->someproperty = $value;
  }
  public function getThatThing() {
    return $this->someproperty;
  }
}

答案 1 :(得分:0)

不要过分思考它。如果属性名称是动态生成的,并且您事先并不知道其值,则访问它的唯一方法是$obj->$prop。我无法想出为什么这会影响表现。