Created
December 25, 2015 20:58
-
-
Save Taluu/2ed4d1d71d5c0db291c4 to your computer and use it in GitHub Desktop.
Benching to see how to easily export a whole php object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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)); |
.... 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
results :
I will try with a real benching tool but I think this is a good estimate...