PHP: performance: splat or reflection statement

In the application I am creating, I need to pass an unknown number of parameters to an unknown class constructor. The class (+ namespace) is the string that is in $ class. Parameters are in an array.

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

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

It works...

But my colleagues do not want to accept this, because the CI server does not understand this line of code. Their solution will likely be:

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

Now: both work fine, so no problem. But my thought is that Reflection is slower than other methods (like PHP 5.6).

Also a question: is it a good reflection, should I use the splat operator from the moment the CI server understands this line?

+4
source share
2 answers

Definitely for the splat operator, why? This is much faster than the reflection approach (I use it and the implementation seems very good). Also, reflection is divided into almost everything related to design, it allows you, for example, to break encapsulation.

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

+7
source

Today I took the time to compare it.
And, as I expected (and Fleshgrinder said): the splat operator is faster.

Testing time:
Reflection: 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;
+7

Source: https://habr.com/ru/post/1547602/


All Articles