Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么空的_uset()方法比有效的方法慢?_Php_Magic Methods_Microbenchmark - Fatal编程技术网

Php 为什么空的_uset()方法比有效的方法慢?

Php 为什么空的_uset()方法比有效的方法慢?,php,magic-methods,microbenchmark,Php,Magic Methods,Microbenchmark,我在玩弄PHP神奇的方法(特别是),在进行微基准测试时,遇到了一个我难以解释的怪癖: 一个具有空主体的\u set方法似乎比一个有效的方法需要更多的时间来运行。下面的代码片段演示了这一点: 类清空器{ 公共函数集($name,$value){} } 类非空发生器{ 公共函数集($name,$value){ $this->{$name}=$value; } } 功能基准($obj){ $start_time=微时间(真); 对于($i=0;$ifoo=42; } 返回microtime(TRUE)

我在玩弄PHP神奇的方法(特别是),在进行微基准测试时,遇到了一个我难以解释的怪癖:

一个具有空主体的
\u set
方法似乎比一个有效的方法需要更多的时间来运行。下面的代码片段演示了这一点:

类清空器{
公共函数集($name,$value){}
}
类非空发生器{
公共函数集($name,$value){
$this->{$name}=$value;
}
}
功能基准($obj){
$start_time=微时间(真);
对于($i=0;$i<10000000;$i++){
$obj->foo=42;
}
返回microtime(TRUE)-$start\u time;
}
printf(“清空设置:%.2f秒\n”,基准测试(新清空设置));
printf(“NonEmptySetter:%.2f秒\n”,基准测试(新的NonEmptySetter));
//输出(在我的Core 2 Duo笔记本电脑上):
//排空时间:4.39秒
//非空计时器:1.28秒

有人能解释为什么会发生这种情况吗?

你不能比较这两种情况,因为最终的结果是不相等的

$o1 = (new NonEmptySetter);
$o1->foo = 42;

$o2 = (new EmptySetter);
$o2->foo = 42;

var_dump($o1, $o2, $o2->foo);
这使得:

object(NonEmptySetter)[1]
  public 'foo' => int 42

object(EmptySetter)[2]

null
并为最后一个添加一个通知:
通知:未定义属性:EmptySetter::$foo

这意味着属性从未设置过,它不存在,fairy dust,我假设那里的不规则性需要时间

如果您正确地声明了类(请注意
$foo
):


时间会被限制:哦,我看这是错误的测试用例

在第一个循环之后,
NonEmptySetter
将具有新的公共属性
foo
。Next循环根本不调用
\u set
方法,它们使用公共属性

class NonEmptySetter {
    public function __set($name, $value) {
        echo 'called only once'; // would be echoed only once.
        $this->{$name} = $value;
    }
}
有效测试

class EmptySetter {
    public function __set($name, $value) {}
}

class NonEmptySetter {
    public function __set($name, $value) {
        $this->{$name} = $value;
    }
}

function benchmark($class_name) {
    $start_time = microtime(TRUE);
    for ($i = 0; $i < 1000000; $i++) {
        $obj = new $class_name();
        $obj->foo = 42;
    }
    return microtime(TRUE) - $start_time;
}

printf("NonEmptySetter: %.2f seconds\n", benchmark('NonEmptySetter'));
printf("EmptySetter: %.2f seconds\n", benchmark('EmptySetter'));
类清空器{
公共函数集($name,$value){}
}
类非空发生器{
公共函数集($name,$value){
$this->{$name}=$value;
}
}
函数基准($class\u name){
$start_time=微时间(真);
对于($i=0;$i<1000000;$i++){
$obj=新的$class_name();
$obj->foo=42;
}
返回microtime(TRUE)-$start\u time;
}
printf(“NonEmptySetter:%.2f秒\n”,基准(“NonEmptySetter”);
printf(“清空设置:%.2f秒\n”,基准(“清空设置”);


空的setter更快。

这有关系吗?你有没有连续访问过1000万次?还有,你到底为什么要使用一种空洞的魔法方法?基准只有在适用于现实情况时才有意义。这是一个精心设计的示例。@SverriM.Olsen,这不重要,但非常有趣:^)@sectus只有当您对PHP的C实现感兴趣时,它才有趣。性能方面,只有在使用空魔法方法1000万次时才有用。。。(并更正我之前的评论:我的意思是说“连续调用该方法”。我不知道为什么我使用“连续访问”作为示例。)@SverriM.Olsen,因此,交易不是在PHP的C实现中,而是错误的测试实现。到底是什么更快<代码>清空设置::$foo不存在。@TOOTSKI,我们不需要检查这段代码的相等性(它们不存在)。我只是说,无论他们做什么,代码的第一次和平都比第二次和平要快。
class EmptySetter {
    public function __set($name, $value) {}
}

class NonEmptySetter {
    public function __set($name, $value) {
        $this->{$name} = $value;
    }
}

function benchmark($class_name) {
    $start_time = microtime(TRUE);
    for ($i = 0; $i < 1000000; $i++) {
        $obj = new $class_name();
        $obj->foo = 42;
    }
    return microtime(TRUE) - $start_time;
}

printf("NonEmptySetter: %.2f seconds\n", benchmark('NonEmptySetter'));
printf("EmptySetter: %.2f seconds\n", benchmark('EmptySetter'));