Skip to content

Instantly share code, notes, and snippets.

@Taluu
Created December 25, 2015 20:58
Show Gist options
  • Save Taluu/2ed4d1d71d5c0db291c4 to your computer and use it in GitHub Desktop.
Save Taluu/2ed4d1d71d5c0db291c4 to your computer and use it in GitHub Desktop.
Benching to see how to easily export a whole php object
<?php
class Foo
{
public $foo;
protected $bar;
private $baz;
public function __construct($foo, $bar, $baz)
{
$this->foo = $foo;
$this->bar = $bar;
$this->baz = $baz;
}
}
function fullReflection($obj)
{
$refl = new \ReflectionObject($obj);
$data = [];
foreach ($refl->getProperties() as $property) {
$property->setAccessible(true);
$data[$property->getName()] = $property->getValue($obj);
}
return $data;
}
function partialReflection($obj)
{
$refl = new \ReflectionObject($obj);
$export = (array) $obj;
$data = [];
foreach ($refl->getProperties() as $property) {
$name = $property->getName();
if (!$property->isPublic()) {
$name = sprintf("\x00%s\x00%s", $property->isPrivate() ? get_class($obj) : '*', $name);
}
$data[$property->getName()] = $export[$name];
}
return $data;
}
function noReflection($obj)
{
$export = (array) $obj;
foreach ($export as $property => $value) {
$name = preg_replace("{^\x00.+\x00}", '', $property);
$data[$property] = $value;
}
return $data;
}
// todo : property access
// todo : no property access, no reflection
$obj = new Foo(
new Foo(
'foo',
null,
'baz'
), 'bar', new Foo(
null,
'bar',
'baz'
)
);
$bench = [];
for ($i = 0; $i < 10000; ++$i) {
$iter = [];
$time = microtime(true);
partialReflection($obj);
$iter[] = microtime(true) - $time;
$time = microtime(true);
noReflection($obj);
$iter[] = microtime(true) - $time;
if ($iter[0] < $iter[1]) {
$bench[] = 'partial reflect';
} elseif ($iter[0] === $iter[1]) {
$bench[] = 'equal';
} else {
$bench[] = 'no reflect';
}
}
var_dump(array_count_values($bench));
@Taluu
Copy link
Author

Taluu commented Dec 25, 2015

results :

php benchReflection.php
array(3) {
  'partial reflect' =>
  int(132)
  'full reflect' =>
  int(9867)
  'equal' =>
  int(1)
}
php benchReflection.php
array(2) {
  'partial reflect' =>
  int(9991)
  'no reflect' =>
  int(9)
}
php benchReflection.php
array(3) {
  'full reflect' =>
  int(9994)
  'equal' =>
  int(1)
  'no reflect' =>
  int(5)
}

I will try with a real benching tool but I think this is a good estimate...

@Taluu
Copy link
Author

Taluu commented Dec 25, 2015

.... BUT, making two replaces seems to be the stuff though ;

<?php

function noRegexReflection($obj)
{
    $export = (array) $obj;
    $class = get_class($obj);

    foreach ($export as $property => $value) {
        $name = str_replace("\x00*\x00", '', $property);
        $name = str_replace("\x00{$class}\x00", '', $name);

        $data[$name] = $value;
    }

    return $data;
}

Same set of data, identified as "no regex and no reflect" :

array(3) {
  'no regex and no reflect' =>
  int(9907)
  'full reflect' =>
  int(86)
  'equal' =>
  int(7)
}
php benchReflection.php
array(3) {
  'no regex and no reflect' =>
  int(9936)
  'full reflect' =>
  int(59)
  'equal' =>
  int(5)
}
php benchReflection.php
array(3) {
  'no regex and no reflect' =>
  int(9921)
  'full reflect' =>
  int(73)
  'equal' =>
  int(6)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment