PHP 5 Reflection API performance

前端 未结 10 1002
不知归路
不知归路 2020-12-02 20:11

I\'m currently considering the use of Reflection classes (ReflectionClass and ReflectionMethod mainly) in my own MVC web framework, because I need to automatically instancia

10条回答
  •  旧巷少年郎
    2020-12-02 20:21

    based on the code that @Alix Axel provided

    So for completeness I decided to wrap each option in a class and include caching of objects where applicable. here was the results and code The results on PHP 5.6 on an i7-4710HQ

    array (
      'Direct' => '5.18932366',
      'Variable' => '5.62969398',
      'Reflective' => '6.59285069',
      'User' => '7.40568614',
    )
    

    Code:

    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(array_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($callbacks[$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;
    }
    
    class foo {
        public static function bar() {
            return __METHOD__;
        }
    }
    
    class TesterDirect {
        public function test() {
            return foo::bar($_SERVER['REQUEST_TIME']);
        }
    }
    
    class TesterVariable {
        private $class = 'foo';
    
        public function test() {
            $class = $this->class;
    
            return $class::bar($_SERVER['REQUEST_TIME']);
        }
    }
    
    class TesterUser {
        private $method = array('foo', 'bar');
    
        public function test() {
            return call_user_func($this->method, $_SERVER['REQUEST_TIME']);
        }
    }
    
    class TesterReflective {
        private $class = 'foo';
        private $reflectionMethod;
    
        public function __construct() {
            $this->reflectionMethod = new ReflectionMethod($this->class, 'bar');
        }
    
        public function test() {
            return $this->reflectionMethod->invoke(null, $_SERVER['REQUEST_TIME']);
        }
    }
    
    $testerDirect = new TesterDirect();
    $testerVariable = new TesterVariable();
    $testerUser = new TesterUser();
    $testerReflective = new TesterReflective();
    
    fputs(STDOUT, var_export(Benchmark(array(
        'Direct' => array($testerDirect, 'test'),
        'Variable' => array($testerVariable, 'test'),
        'User' => array($testerUser, 'test'),
        'Reflective' => array($testerReflective, 'test')
    ), 10000000), true));
    

提交回复
热议问题