Skip to content

Instantly share code, notes, and snippets.

@bwg
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bwg/f9c1a18d4222f94258e5 to your computer and use it in GitHub Desktop.
Save bwg/f9c1a18d4222f94258e5 to your computer and use it in GitHub Desktop.
comparing subclasses that call parent constructors vs. cloning empty object
<?php
$iterations = 100000;
class zero {
public static function one() {
static $empties = [];
$empty = &$empties[static::class];
if (!isset($empty)) {
$empty = new static();
}
return clone $empty;
}
public static function reflect() {
static $empties = [];
$empty = &$empties[static::class];
if (!isset($empty)) {
$rc = new ReflectionClass(static::class);
$empty = $rc->newInstanceWithoutConstructor();
}
return clone $empty;
}
}
class one extends zero {
public function __construct() {
}
}
class two extends one {
public function __construct() {
parent::__construct();
}
}
class three extends two {
public function __construct() {
parent::__construct();
}
}
echo "PHP Version ".phpversion()."\n\n";
foreach (['zero', 'one', 'two', 'three'] as $class) {
echo str_repeat('-', 50)."\n";
echo "Testing {$class} over ".number_format($iterations)." iterations:\n\n";
// -- constructor ---------------------------------------------------------
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$obj = new $class();
}
$end = microtime(true);
$duration = ($end - $start) * 1000;
echo str_pad('new '.$class.'()', 30)."{$duration} ms\n";
// -- one -----------------------------------------------------------------
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$obj = $class::one();
}
$end = microtime(true);
$duration = ($end - $start) * 1000;
echo str_pad($class.'::one()', 30)."{$duration} ms\n";
// -- reflect -------------------------------------------------------------
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$obj = $class::reflect();
}
$end = microtime(true);
$duration = ($end - $start) * 1000;
$totals[$class]['reflect'] = $duration;
echo str_pad($class.'::reflect()', 30)."{$duration} ms\n";
}
PHP Version 5.6.3
--------------------------------------------------
Testing zero over 100,000 iterations:
new zero() 38.282155990601 ms
zero::one() 190.81401824951 ms
zero::reflect() 189.72611427307 ms
--------------------------------------------------
Testing one over 100,000 iterations:
new one() 140.82789421082 ms
one::one() 188.9488697052 ms
one::reflect() 181.81800842285 ms
--------------------------------------------------
Testing two over 100,000 iterations:
new two() 259.14406776428 ms
two::one() 177.83093452454 ms
two::reflect() 175.33683776855 ms
--------------------------------------------------
Testing three over 100,000 iterations:
new three() 374.38988685608 ms
three::one() 173.34198951721 ms
three::reflect() 190.68098068237 ms
@hikmet
Copy link

hikmet commented Dec 18, 2014

isn't this supposed to be more like

public static function one() {
    static $empties = [];

    $empty = &$empties[static::class];

    if (!isset($empty)) {
        $empty = new static();
    }

    return clone $empty;
}

same for the other reflect version

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