@ 2014-08-26T14:48:07Z <?php
class A {
}
class B {
public $a;
public function __construct(A $a) {
$this->a = $a;
}
}
class C {
public $b;
public function __construct(B $b) {
$this->b = $b;
}
}
class D {
public $c;
public function __construct(C $c) {
$this->c = $c;
}
}
class E {
public $d;
public function __construct(D $d) {
$this->d = $d;
}
}
class F {
public $e;
public function __construct(E $e) {
$this->e = $e;
}
}
class G {
public $f;
public function __construct(F $f) {
$this->f = $f;
}
}
class H {
public $g;
public function __construct(G $g) {
$this->g = $g;
}
}
class I {
public $h;
public function __construct(H $h) {
$this->h = $h;
}
}
class J {
public $i;
public function __construct(I $i) {
$this->i = $i;
}
}
class K {
public $j;
public function __construct(K $k) {
$this->k = $k;
}
}
class Dice {
private $rules = [];
private $cache = [];
private $instances = [];
public function addRule($name, Rule $rule) {
$this->rules[ltrim($name, '\\')] = $rule;
}
public function getRule($name) {
if (isset($this->rules[ltrim($name, '\\')])) return $this->rules[ltrim($name, '\\')];
foreach ($this->rules as $key => $rule) {
if ($rule->instanceOf === null && $key !== '*' && is_subclass_of($name, $key) && $rule->inherit === true) return $rule;
}
return isset($this->rules['*']) ? $this->rules['*'] : new Rule;
}
public function create($component, array $args = [], $forceNewInstance = false) {
if (!$forceNewInstance && isset($this->instances[$component])) return $this->instances[$component];
if (!isset($this->cache[$component])) {
$rule = $this->getRule($component);
$class = new \ReflectionClass(empty($rule->instanceOf) ? $component : $rule->instanceOf);
$constructor = $class->getConstructor();
$params = $constructor ? $this->getParams($constructor, $rule) : null;
$this->cache[$component] = function($args, $forceNewInstance) use ($component, $rule, $class, $constructor, $params) {
if ($rule->shared) {
if ($constructor) {
try {
$this->instances[$component] = $object = $class->newInstanceWithoutConstructor();
$constructor->invokeArgs($object, $params($args));
} catch (\ReflectionException $r) {
$this->instances[$component] = $object = $class->newInstanceArgs($params($args));
}
} else {
$this->instances[$component] = $object = $class->newInstanceWithoutConstructor();
}
}
else $object = $params ? $class->newInstanceArgs($params($args)) : new $class->name;
if (!empty($rule->call)) foreach ($rule->call as $call) $class->getMethod($call[0])->invokeArgs($object, call_user_func($this->getParams($class->getMethod($this->expand($call[0])), new Rule), $call[1]));
return $object;
};
}
return $this->cache[$component]($args, $forceNewInstance);
}
private function expand($param, array $share = []) {
if (is_array($param)) return array_map(function($p) use($share) { return $this->expand($p, $share); }, $param);
if ($param instanceof Instance) return $this->create($param->name, $share);
else if (is_callable($param)) return $param($this);
return $param;
}
private function getParams(\ReflectionMethod $method, Rule $rule) {
$subs = empty($rule->substitutions) ? null :$rule->substitutions;
$paramClasses = [];
foreach ($method->getParameters() as $param) $paramClasses[] = $param->getClass() ? $param->getClass()->name : null;
return function($args) use ($paramClasses, $rule, $subs) {
$share = empty($rule->shareInstances) ? [] : array_map([$this, 'create'], $rule->shareInstances);
if (!empty($share) || !empty($rule->constructParams)) $args = array_merge($args, $this->expand($rule->constructParams, $share), $share);
$parameters = [];
foreach ($paramClasses as $class) {
if (!empty($args)) for ($i = 0; $i < count($args); $i++) {
if ($class && $args[$i] instanceof $class) {
$parameters[] = array_splice($args, $i, 1)[0];
continue 2;
}
}
if (!empty($subs) && isset($subs[$class])) $parameters[] = is_string($subs[$class]) ? $this->create($subs[$class]) : $this->expand($subs[$class]);
else if (!empty($class)) $parameters[] = $this->create($class, $share, !empty($rule->newInstances) && in_array(strtolower($class), array_map('strtolower', $rule->newInstances)));
else if (!empty($args)) $parameters[] = array_shift($args);
}
return $parameters;
};
}
}
class Rule {
public $shared = false;
public $constructParams = [];
public $substitutions = [];
public $newInstances = [];
public $instanceOf;
public $call = [];
public $inherit = true;
public $shareInstances = [];
}
class Instance {
public $name;
public function __construct($instance) {
$this->name = $instance;
}
}
class Dice2 {
private $rules = [];
private $cache = [];
private $instances = [];
public function addRule($name, Rule $rule) {
$this->rules[ltrim($name, '\\')] = $rule;
}
public function getRule($name) {
if (isset($this->rules[ltrim($name, '\\')])) return $this->rules[ltrim($name, '\\')];
foreach ($this->rules as $key => $rule) {
if ($rule->instanceOf === null && $key !== '*' && is_subclass_of($name, $key) && $rule->inherit === true) return $rule;
}
return isset($this->rules['*']) ? $this->rules['*'] : new Rule;
}
public function create($component, array $args = [], $forceNewInstance = false) {
if (!$forceNewInstance && isset($this->instances[$component])) return $this->instances[$component];
if (!isset($this->cache[$component])) {
$rule = $this->getRule($component);
$class = new \ReflectionClass(empty($rule->instanceOf) ? $component : $rule->instanceOf);
$constructor = $class->getConstructor();
$params = $constructor ? $this->getParams($constructor, $rule) : null;
$this->cache[$component] = function($args, $forceNewInstance) use ($component, $rule, $class, $constructor, $params) {
if ($rule->shared) {
$this->instances[$component] = $object = $class->isInternal() && $constructor ? $class->newInstanceArgs($params($args)) : $class->newInstanceWithoutConstructor();
if ($constructor && !$class->isInternal()) $constructor->invokeArgs($object, $params($args));
}
else $object = $params ? new $class->name(...$params($args)) : new $class->name;
if (!empty($rule->call)) foreach ($rule->call as $call) $class->getMethod($call[0])->invokeArgs($object, call_user_func($this->getParams($class->getMethod($this->expand($call[0])), new Rule), $call[1]));
return $object;
};
}
return $this->cache[$component]($args, $forceNewInstance);
}
private function expand($param, array $share = []) {
if (is_array($param)) return array_map(function($p) use($share) { return $this->expand($p, $share); }, $param);
if ($param instanceof Instance) return $this->create($param->name, $share);
else if (is_callable($param)) return $param($this);
return $param;
}
private function getParams(\ReflectionMethod $method, Rule $rule) {
$subs = empty($rule->substitutions) ? null :$rule->substitutions;
$paramClasses = [];
foreach ($method->getParameters() as $param) $paramClasses[] = $param->getClass() ? $param->getClass()->name : null;
return function($args) use ($paramClasses, $rule, $subs) {
$share = empty($rule->shareInstances) ? [] : array_map([$this, 'create'], $rule->shareInstances);
if (!empty($share) || !empty($rule->constructParams)) $args = array_merge($args, $this->expand($rule->constructParams, $share), $share);
$parameters = [];
foreach ($paramClasses as $class) {
if (!empty($args)) for ($i = 0; $i < count($args); $i++) {
if ($class && $args[$i] instanceof $class) {
$parameters[] = array_splice($args, $i, 1)[0];
continue 2;
}
}
if (!empty($subs) && isset($subs[$class])) $parameters[] = is_string($subs[$class]) ? $this->create($subs[$class]) : $this->expand($subs[$class]);
else if (!empty($class)) $parameters[] = $this->create($class, $share, !empty($rule->newInstances) && in_array(strtolower($class), array_map('strtolower', $rule->newInstances)));
else if (!empty($args)) $parameters[] = array_shift($args);
}
return $parameters;
};
}
}
$dice1 = new Dice;
$dice2 = new Dice2;
$j1 = $dice1->create('J');
$j2 = $dice2->create('J');
$t1 = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$j = $dice1->create('J');
}
$t2 = microtime(true);
echo 'dice1: ' . ($t2 - $t1) . "\n\n";
$t1 = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$j = $dice2->create('J');
}
$t2 = microtime(true);
echo 'dice1: ' . ($t2 - $t1) . "\n\n";
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 7.4.0 0.010 0.220 14.85 7.3.12 0.003 0.305 14.68 7.3.11 0.010 0.231 15.01 7.3.10 0.006 0.215 14.98 7.3.9 0.003 0.236 14.83 7.3.8 0.007 0.209 15.11 7.3.7 0.010 0.192 15.03 7.3.6 0.007 0.256 15.06 7.3.5 0.003 0.203 15.00 7.3.4 0.010 0.185 14.91 7.3.3 0.003 0.214 14.89 7.3.2 0.003 0.219 16.66 7.3.1 0.016 0.194 16.72 7.3.0 0.003 0.236 16.48 7.2.25 0.007 0.343 15.47 7.2.24 0.003 0.265 15.17 7.2.23 0.003 0.256 15.30 7.2.22 0.000 0.264 15.44 7.2.21 0.003 0.253 15.02 7.2.20 0.003 0.230 15.33 7.2.19 0.003 0.245 15.30 7.2.18 0.006 0.255 15.38 7.2.17 0.007 0.286 15.07 7.2.0 0.007 0.130 19.46 7.1.33 0.007 0.313 15.84 7.1.32 0.007 0.338 15.78 7.1.31 0.003 0.369 15.65 7.1.30 0.003 0.381 15.82 7.1.29 0.000 0.302 15.70 7.1.28 0.003 0.305 15.98 7.1.27 0.003 0.332 15.81 7.1.26 0.010 0.299 15.91 7.1.7 0.000 0.160 17.08 7.1.6 0.007 0.193 19.40 7.1.5 0.007 0.204 17.00 7.1.0 0.003 0.293 22.36 7.0.20 0.007 0.161 16.89 7.0.14 0.000 0.300 22.07 7.0.12 0.003 0.307 22.04 7.0.11 0.000 0.307 22.09 7.0.10 0.007 0.283 22.16 7.0.9 0.007 0.297 22.06 7.0.8 0.007 0.297 22.16 7.0.7 0.003 0.293 22.07 7.0.6 0.000 0.303 22.15 7.0.5 0.000 0.307 22.13 7.0.4 0.007 0.300 22.12 7.0.3 0.003 0.290 22.15 7.0.2 0.010 0.270 21.98 7.0.1 0.003 0.303 22.05 7.0.0 0.003 0.290 22.04 5.6.28 0.000 0.560 21.23 5.6.26 0.007 0.503 21.19 5.6.25 0.010 0.500 21.20 5.6.24 0.003 0.487 20.95 5.6.23 0.010 0.497 21.20 5.6.22 0.003 0.513 20.89 5.6.21 0.007 0.477 21.17 5.6.20 0.007 0.490 20.95 5.6.19 0.000 0.503 20.87 5.6.18 0.000 0.510 20.92 5.6.17 0.007 0.497 21.00 5.6.16 0.000 0.503 21.13 5.6.15 0.007 0.500 21.08 5.6.14 0.000 0.490 21.04 5.6.13 0.003 0.500 21.05 5.6.12 0.003 0.513 20.86 5.6.11 0.007 0.503 21.19 5.6.10 0.000 0.510 21.03 5.6.9 0.007 0.503 20.89 5.6.8 0.000 0.503 20.43 5.6.7 0.007 0.493 20.47 5.6.6 0.003 0.500 20.35 5.6.5 0.000 0.490 20.35 5.6.4 0.003 0.500 20.55 5.6.3 0.000 0.500 20.53 5.6.2 0.000 0.490 20.41 5.6.1 0.003 0.500 20.51 5.6.0 0.007 0.493 20.54 5.5.38 0.000 0.073 17.77 5.5.37 0.007 0.063 17.68 5.5.36 0.007 0.073 17.63 5.5.35 0.003 0.070 17.61 5.5.34 0.000 0.073 18.28 5.5.33 0.010 0.063 18.03 5.5.32 0.003 0.070 18.10 5.5.31 0.003 0.073 18.26 5.5.30 0.003 0.073 18.19 5.5.29 0.003 0.073 18.22 5.5.28 0.007 0.073 18.22 5.5.27 0.003 0.077 18.12 5.5.26 0.003 0.073 18.09 5.5.25 0.013 0.063 17.91 5.5.24 0.007 0.067 17.64 5.5.23 0.007 0.067 17.61 5.5.22 0.003 0.067 17.53 5.5.21 0.010 0.063 17.41 5.5.20 0.003 0.067 17.58 5.5.19 0.000 0.070 17.38 5.5.18 0.000 0.077 17.38 5.5.16 0.003 0.070 17.61 5.5.15 0.003 0.070 17.57 5.5.14 0.010 0.063 17.61 5.5.13 0.007 0.067 17.51 5.5.12 0.003 0.067 17.36 5.5.11 0.003 0.067 17.30 5.5.10 0.007 0.067 17.48 5.5.9 0.003 0.067 17.53 5.5.8 0.000 0.050 17.31 5.5.7 0.003 0.070 17.34 5.5.6 0.003 0.067 17.52 5.5.5 0.007 0.063 17.24 5.5.4 0.003 0.063 17.24 5.5.3 0.007 0.063 17.47 5.5.2 0.000 0.073 17.52 5.5.1 0.003 0.060 17.52 5.5.0 0.000 0.063 17.39 5.4.45 0.003 0.073 19.42 5.4.44 0.007 0.070 19.45 5.4.43 0.000 0.077 19.49 5.4.42 0.007 0.067 19.41 5.4.41 0.003 0.070 19.23 5.4.40 0.000 0.070 19.20 5.4.39 0.003 0.070 19.13 5.4.38 0.003 0.067 19.00 5.4.37 0.007 0.063 19.00 5.4.36 0.007 0.063 19.05 5.4.35 0.000 0.073 19.16 5.4.34 0.003 0.050 19.25 5.4.32 0.000 0.073 19.04 5.4.31 0.007 0.067 19.19 5.4.30 0.007 0.067 18.95 5.4.29 0.003 0.067 19.15 5.4.28 0.000 0.067 18.95 5.4.27 0.000 0.070 19.00 5.4.26 0.000 0.060 19.00 5.4.25 0.000 0.073 18.99 5.4.24 0.003 0.067 19.34 5.4.23 0.007 0.067 19.23 5.4.22 0.003 0.067 19.35 5.4.21 0.003 0.060 19.04 5.4.20 0.003 0.063 18.98 5.4.19 0.000 0.070 19.18 5.4.18 0.000 0.070 19.14 5.4.17 0.007 0.057 19.18 5.4.16 0.007 0.063 19.02 5.4.15 0.007 0.070 19.00 5.4.14 0.003 0.060 16.43 5.4.13 0.003 0.067 16.42 5.4.12 0.003 0.063 16.58 5.4.11 0.003 0.067 16.36 5.4.10 0.007 0.063 16.48 5.4.9 0.000 0.063 16.57 5.4.8 0.003 0.063 16.57 5.4.7 0.007 0.060 16.55 5.4.6 0.007 0.060 16.29 5.4.5 0.003 0.063 16.68 5.4.4 0.003 0.060 16.50 5.4.3 0.000 0.063 16.39 5.4.2 0.003 0.060 16.67 5.4.1 0.003 0.067 16.44 5.4.0 0.003 0.063 16.02
preferences:dark mode live preview
34.95 ms | 400 KiB | 5 Q