PHP:性能:splat运算符或反射

时间:2014-07-08 14:16:58

标签: php php-5.6

在我正在创建的应用程序中,我需要将未知数量的参数传递给类的未知构造函数。 类(+ namespace)是一个字符串,在$ class中。 参数在一个数组中。

这个应用程序将在几个月内部署,所以我们认为我们可以在PHP 5.6中开发它。 所以我认为解决方法是:

$instance = new $class(...$args);

这是有效的......

但是我的同事不想接受这个,因为CI服务器不理解这行代码。 他们的解决方案宁愿是:

$reflect = new \ReflectionClass($class);
$instance = $reflect->newInstanceArgs($args)

现在:两者都工作正常,所以这不是问题。 但我的想法是,反射比其他方式慢(如PHP 5.6 splat运算符)。

还有一个问题:反思是一种好方法,我应该从CI服务器理解该行的那一刻起使用splat运算符吗?

2 个答案:

答案 0 :(得分:7)

绝对选择splat运算符,为什么?它比反射方法快得多(我使用它并且实现似乎非常好)。反射也会破坏与设计有关的任何事情,例如,它允许你打破封装。

PS:不是$instance = new $class(...$args);吗?

答案 1 :(得分:7)

今天我找到了时间进行基准测试 这就像我预期的那样(和Fleshgrinder说):splat运算符更快。

基准时间:
反思:11.686084032059s
Splat:6.8125338554382s

几乎有一半的时间......这很严重......

基准(通过http://codepad.org/jqOQkaZR):

<?php

require "autoload.php";

function convertStdToCollectionReflection(array $stds, $entity, $initVars)
{
    $records = array();
    $class = $entity . '\\Entity';
    foreach ($stds as $record) {
        $args = array();
        foreach ($initVars as $var) {
            $args[] = $record->$var;
        }
        $reflect = new \ReflectionClass($class);
        $records[] = $reflect->newInstanceArgs($args);
    }

    return $records;
}

function convertStdToCollectionSplat(array $stds, $entity, $initVars)
{
    $records = array();
    $class = $entity . '\\Entity';
    foreach ($stds as $record) {
        $args = array();
        foreach ($initVars as $var) {
            $args[] = $record->$var;
        }
        $records[] = new $class(...$args);
    }

    return $records;
}

$dummyObject = array();
for ($i = 0; $i < 10; $i++) {
    $dummyclass = new \stdClass();
    $dummyclass->id = $i;
    $dummyclass->description = 'Just a number... ' . $i;
    $dummyObject[] = $dummyclass;
}

print 'Start Reflection test' . PHP_EOL;
$reflectionStart = microtime(true);

for($i = 0; $i < 1000000; $i++) {
    convertStdToCollectionReflection(
        $dummyObject,
        'Xcs\Core\Record',
        array(
            'id',
            'description'
        )
    );
}

$reflectionEnd = microtime(true);

print 'Start Splat test' . PHP_EOL;
$splatStart = microtime(true);

for($i = 0; $i < 1000000; $i++) {
    convertStdToCollectionSplat(
        $dummyObject,
        'Xcs\Core\Record',
        array(
            'id',
            'description'
        )
    );
}

$splatEnd = microtime(true);

print PHP_EOL . 'OUTPUT:' . PHP_EOL;
print 'Reflection: ' . ($reflectionEnd - $reflectionStart) . 's' . PHP_EOL;
print 'Splat: ' . ($splatEnd - $splatStart) . 's' . PHP_EOL;
相关问题