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

Bla*_*aat 4 php php-5.6

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

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

$instance = new $class(...$args);
Run Code Online (Sandbox Code Playgroud)

这工作......

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

$reflect = new \ReflectionClass($class);
$instance = $reflect->newInstanceArgs($args)
Run Code Online (Sandbox Code Playgroud)

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

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

Fle*_*der 7

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

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

  • 更快的速度并不是一个好的指标.您可以根据自己的发现发布基准吗? (2认同)

Bla*_*aat 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;
Run Code Online (Sandbox Code Playgroud)