Home

Awesome

Reflection benchmark

This is a benchmark of all methods allowing to access private properties (read and write).

We all know that micro-optimization is most of the time useless. However, if you write libraries or frameworks making extensive use of reflection techniques, you probably wonder how to spare the impact of using reflection to your users. This comparison is here to help by maintaining an up-to-date and reproducible summary.

Methods

$reflectionProperty = new ReflectionProperty($object, $property);
$reflectionProperty->setAccessible(true);

$value = $reflectionProperty->getValue($object);
$reflectionProperty->setValue($object, 'new value');
$array = (array) $object;

$protectedKey = "\0*\0" . $this->propertyName;
$privateKey = "\0" . get_class($this->object) . "\0" . $this->propertyName;

if (array_key_exists($protectedKey, $array)) {
    $value = $array[$protectedKey];
} elseif (array_key_exists($privateKey, $array)) {
    $value = $array[$privateKey];
}
$get = Closure::bind(function($object, $prop) { return $object->{$prop}; }, null, $object);
$set = Closure::bind(function($object, $prop, $value) { $object->{$prop} = $value; }, null, $object);

$value = $get($object, $property);
$set($object, $property, 'new value');

Running the benchmarks

Install the dependencies using Composer:

$ composer install

Run the benchmarks:

$ php -n vendor/bin/athletic -p benchmarks -b vendor/autoload.php

Results

Those results were obtained on a development OS X machine using PHP 7.1.10. Feel free to run the benchmark on your server and update these results if you get different ones. Be aware that "slightly faster" means that it's probably not significant, whereas "faster" or "way faster" means that results are expected to be reproducible for the same PHP version.

The closure is slightly faster.

Reflection is way faster, the closure is almost as fast.

The array cast is way faster, with the closure not far behind.

The closure is slightly faster.

Reflection is slightly faster.

Summary

With PHP 7, if you were to use only one method for all operations then use the closure. It is the solution that provides the best performances accross all operations.

Raw results

Benchmark\ReadAllPropertiesOnOneObjectEvent
    Method Name   Iterations    Average Time      Ops/second
    ----------  ------------  --------------    -------------
    reflection: [10,000    ] [0.0000030814409] [324,523.50188]
    arrayCast : [10,000    ] [0.0000008020163] [1,246,857.51657]
    closure   : [10,000    ] [0.0000010994911] [909,511.66623]


Benchmark\ReadSinglePropertyOnManyObjectsEvent
    Method Name   Iterations    Average Time      Ops/second
    ----------  ------------  --------------    -------------
    reflection: [100,000   ] [0.0000001455283] [6,871,514.93306]
    arrayCast : [100,000   ] [0.0000002697277] [3,707,442.63338]
    closure   : [100,000   ] [0.0000001647019] [6,071,573.94943]


Benchmark\ReadSinglePropertyOnOneObjectEvent
    Method Name   Iterations    Average Time      Ops/second
    ----------  ------------  --------------    -------------
    reflection: [100,000   ] [0.0000004917526] [2,033,542.78179]
    arrayCast : [100,000   ] [0.0000004168963] [2,398,677.79182]
    closure   : [100,000   ] [0.0000004045892] [2,471,642.98721]


Benchmark\WriteSinglePropertyOnManyObjectsEvent
    Method Name   Iterations    Average Time      Ops/second
    ----------  ------------  --------------    -------------
    reflection: [50,000    ] [0.0000001499557] [6,668,633.93538]
    closure   : [50,000    ] [0.0000001540565] [6,491,122.94169]


Benchmark\WriteSinglePropertyOnOneObjectEvent
    Method Name   Iterations    Average Time      Ops/second
    ----------  ------------  --------------    -------------
    reflection: [50,000    ] [0.0000005018568] [1,992,600.26414]
    closure   : [50,000    ] [0.0000004431438] [2,256,603.61117]

Contribute

Please provide fixes and improvements through pull requests.

Don't forget to update the results in the README.

Credits

This is a compilation of the methods Marco Pivetta exposed on his blog.

Read also this article.