当前位置:  开发笔记 > 编程语言 > 正文

PHP 5 Reflection API性能

如何解决《PHP5ReflectionAPI性能》经验,为你挑选了4个好方法。

我目前正在考虑在我自己的MVC Web框架中使用Reflection类(主要是ReflectionClass和ReflectionMethod),因为我需要自动实例化控制器类并调用他们的方法而不需要任何必需的配置("约定优于配置"方法).

我担心性能,即使我认为数据库请求可能是比实际PHP代码更大的瓶颈.

所以,我想知道从性能的角度来看,是否有人对PHP 5 Reflection有任何好的或坏的体验.

此外,我很想知道任何一个流行的PHP框架(CI,Cake,Symfony等)是否实际使用Reflection.



1> Alix Axel..:

我对这3个选项进行了基准测试(另一个基准测试不是拆分CPU周期,而是4年前):

class foo {
    public static function bar() {
        return __METHOD__;
    }
}

function directCall() {
    return foo::bar($_SERVER['REQUEST_TIME']);
}

function variableCall() {
    return call_user_func(array('foo', 'bar'), $_SERVER['REQUEST_TIME']);
}

function reflectedCall() {
    return (new ReflectionMethod('foo', 'bar'))->invoke(null, $_SERVER['REQUEST_TIME']);
}

1,000,000次迭代所需的绝对时间:

print_r(Benchmark(array('directCall','variableCall','reflectCall'),1000000));

Array
(
    [directCall] => 4.13348770
    [variableCall] => 6.82747173
    [reflectedCall] => 8.67534351
)

相对时间,也有1,000,000次迭代(单独运行):

ph() - >转储(Benchmark(array('directCall','variableCall','reflectCall'),1000000,true));

Array
(
    [directCall] => 1.00000000
    [variableCall] => 1.67164707
    [reflectedCall] => 2.13174915
)

似乎反射性能在5.4.7(从~500%下降到~213%)大大增加.

这是Benchmark()我使用的功能,如果有人想重新运行这个基准测试:

function Benchmark($callbacks, $iterations = 100, $relative = false)
{
    set_time_limit(0);

    if (count($callbacks = array_filter((array) $callbacks, 'is_callable')) > 0)
    {
        $result = array_fill_keys($callbacks, 0);
        $arguments = array_slice(func_get_args(), 3);

        for ($i = 0; $i < $iterations; ++$i)
        {
            foreach ($result as $key => $value)
            {
                $value = microtime(true);
                call_user_func_array($key, $arguments);
                $result[$key] += microtime(true) - $value;
            }
        }

        asort($result, SORT_NUMERIC);

        foreach (array_reverse($result) as $key => $value)
        {
            if ($relative === true)
            {
                $value /= reset($result);
            }

            $result[$key] = number_format($value, 8, '.', '');
        }

        return $result;
    }

    return false;
}


+1为雄辩的回复和提供的细节.

2> Kornel..:

不要担心.安装Xdebug并确保瓶颈在哪里.

使用反射需要花费成本,但这是否重要取决于您正在做什么.如果使用Reflection实现控制器/请求调度程序,那么每个请求只使用一次.绝对可以忽略不计.

如果使用反射实现ORM层,则将其用于每个对象甚至每次访问属性,并创建数百或数千个对象,然后它可能成本很高.



3> 小智..:

在我的机器上调用静态功能100万次将花费约0.31秒.使用ReflectionMethod时,它的成本约为1.82秒.这意味着使用Reflection API的成本要高出约500%.

这是我使用的代码:

invokeArgs(null, array('f'));
}

echo ($b=microtime(true) - $s)."\n";

echo 100/$a*$b;

显然,实际影响取决于您希望进行的呼叫次数


它可能要贵500%,但每次通话平均只有1.82微秒.
此测试不正确,因为反射方法的实例应该只创建一次.不在循环中.

4> vartec..:

此外,我很想知道任何一个流行的PHP框架(CI,Cake,Symfony等)是否实际使用Reflection.

http://framework.zend.com/manual/en/zend.server.reflection.html

"通常,此功能仅供框架的服务器类开发人员使用."

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有