PHP: Performance: splat operator or reflection

时光毁灭记忆、已成空白 提交于 2021-02-20 19:27:28

问题


In an app that I'm creating, I need to pass an unknown number of parameters to an unknown constructor of a class. The class (+ namespace) is a string, that is in $class. The parameters are in an array.

This application will be deployed over a couple of months, so we thought we could develop it already in PHP 5.6. So I thought that the solution of this would be:

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

This is working...

But my collegues don't want to accept this, because the CI server does not understand this line of code. Their solution would rather be:

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

Now: both are working fine, so that's not the problem. But my thought is that Reflection is slower then using other ways (like the PHP 5.6 splat operator).

Also the question: is reflection a good way, of should I use the splat operator from the moment the CI server does understand that line?


回答1:


Definitely go for the splat operator, why? It's much faster than the reflection approach (I'm using it and the implementation seems to be very good). Also reflection breaks just about anything that has to do with design, it allows you to break encapsulation for instance.

PS: Isn't it $instance = new $class(...$args);?




回答2:


Today I've found the time to benchmark it.
And it's like I've expected (and Fleshgrinder said): the splat operator is faster.

Benchmark times:
Reflection: 11.686084032059s
Splat: 6.8125338554382s

Almost the half of time... That's serious...

Benchmark (via 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;


来源:https://stackoverflow.com/questions/24634165/php-performance-splat-operator-or-reflection

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!