@ 2014-08-26T15:04:32Z <?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->invoke($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);
foreach ($paramClasses as $class) {
if (!empty($args)) for ($i = 0; $i < count($args); $i++) {
if ($class && $args[$i] instanceof $class) {
yield array_splice($args, $i, 1)[0];
continue 2;
}
}
if (!empty($subs) && isset($subs[$class])) yield is_string($subs[$class]) ? $this->create($subs[$class]) : $this->expand($subs[$class]);
else if (!empty($class)) yield $this->create($class, $share, !empty($rule->newInstances) && in_array(strtolower($class), array_map('strtolower', $rule->newInstances)));
else if (!empty($args)) yield array_shift($args);
}
};
}
}
$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.1 0.013 0.245 15.07 7.4.0 0.010 0.324 15.30 7.3.13 0.007 0.251 15.05 7.3.12 0.007 0.334 14.72 7.3.11 0.008 0.291 14.86 7.3.10 0.007 0.245 15.20 7.3.9 0.002 0.222 15.09 7.3.8 0.003 0.226 14.98 7.3.7 0.002 0.242 15.00 7.3.6 0.005 0.240 15.16 7.3.5 0.003 0.219 15.15 7.3.4 0.008 0.281 15.09 7.3.3 0.010 0.216 14.84 7.3.2 0.005 0.215 16.70 7.3.1 0.003 0.230 16.72 7.3.0 0.009 0.230 16.63 7.2.26 0.003 0.276 15.42 7.2.25 0.002 0.392 15.32 7.2.24 0.005 0.319 15.39 7.2.23 0.003 0.311 15.15 7.2.22 0.005 0.324 15.46 7.2.21 0.000 0.332 15.19 7.2.20 0.008 0.249 15.15 7.2.19 0.008 0.314 15.08 7.2.18 0.005 0.335 15.20 7.2.17 0.005 0.271 15.31 7.2.16 0.000 0.393 15.34 7.2.15 0.010 0.299 17.00 7.2.14 0.003 0.272 16.91 7.2.13 0.005 0.309 16.85 7.2.12 0.010 0.301 16.89 7.2.11 0.005 0.294 16.82 7.2.10 0.005 0.251 16.95 7.2.9 0.003 0.301 16.96 7.2.8 0.008 0.288 16.93 7.2.7 0.008 0.317 16.83 7.2.6 0.007 0.300 16.78 7.2.5 0.003 0.260 16.92 7.2.4 0.003 0.277 16.96 7.2.3 0.007 0.323 17.10 7.2.2 0.008 0.261 16.90 7.2.1 0.012 0.303 16.88 7.2.0 0.005 0.244 17.67 7.1.33 0.003 0.359 15.79 7.1.32 0.007 0.409 15.79 7.1.31 0.005 0.368 15.86 7.1.30 0.003 0.383 15.80 7.1.29 0.007 0.395 15.77 7.1.28 0.003 0.410 15.75 7.1.27 0.007 0.373 15.68 7.1.26 0.008 0.371 15.81 7.1.25 0.003 0.400 15.96 7.1.24 0.003 0.385 15.86 7.1.23 0.003 0.364 15.56 7.1.22 0.000 0.362 15.99 7.1.21 0.010 0.326 15.85 7.1.20 0.007 0.377 15.96 7.1.19 0.007 0.438 15.91 7.1.18 0.007 0.416 15.97 7.1.17 0.007 0.344 15.80 7.1.16 0.007 0.358 15.77 7.1.15 0.003 0.321 15.93 7.1.14 0.019 0.344 15.91 7.1.13 0.007 0.464 15.94 7.1.12 0.003 0.387 15.84 7.1.11 0.010 0.420 16.00 7.1.10 0.003 0.453 15.95 7.1.9 0.000 0.385 15.73 7.1.8 0.007 0.427 15.93 7.1.7 0.005 0.314 16.56 7.1.6 0.008 0.319 17.71 7.1.5 0.008 0.298 16.35 7.1.4 0.010 0.424 15.95 7.1.3 0.003 0.385 15.76 7.1.2 0.003 0.376 15.92 7.1.1 0.003 0.468 15.81 7.1.0 0.008 0.335 19.14 7.0.33 0.000 0.379 15.55 7.0.32 0.000 0.416 15.38 7.0.31 0.003 0.408 15.41 7.0.30 0.000 0.394 15.48 7.0.29 0.000 0.469 15.18 7.0.28 0.007 0.458 15.23 7.0.27 0.003 0.422 15.28 7.0.26 0.003 0.457 15.47 7.0.25 0.003 0.383 15.52 7.0.24 0.003 0.521 15.33 7.0.23 0.006 0.424 15.22 7.0.22 0.007 0.543 15.45 7.0.21 0.007 0.382 15.59 7.0.20 0.007 0.337 16.24 7.0.19 0.003 0.433 15.24 7.0.18 0.007 0.358 15.22 7.0.17 0.009 0.501 15.48 7.0.16 0.003 0.415 15.34 7.0.15 0.003 0.440 15.50 7.0.14 0.002 0.462 18.82 7.0.13 0.013 0.482 15.21 7.0.12 0.003 0.371 18.67 7.0.11 0.010 0.346 18.71 7.0.10 0.003 0.425 18.82 7.0.9 0.005 0.359 18.88 7.0.8 0.005 0.429 18.75 7.0.7 0.003 0.378 18.79 7.0.6 0.000 0.368 18.63 7.0.5 0.002 0.440 19.00 7.0.4 0.003 0.348 17.72 7.0.3 0.007 0.373 17.92 7.0.2 0.003 0.347 17.73 7.0.1 0.002 0.395 17.71 7.0.0 0.007 0.368 17.84 5.6.40 0.007 0.710 14.86 5.6.39 0.007 0.923 15.12 5.6.38 0.003 0.800 15.06 5.6.37 0.000 0.844 14.95 5.6.36 0.000 0.855 15.06 5.6.35 0.007 0.893 15.18 5.6.34 0.007 0.844 14.76 5.6.33 0.007 0.968 15.09 5.6.32 0.000 0.844 14.79 5.6.31 0.003 0.750 14.93 5.6.30 0.010 0.706 15.00 5.6.29 0.007 0.888 14.73 5.6.28 0.005 0.725 18.20 5.6.27 0.010 0.705 15.05 5.6.26 0.005 0.745 18.23 5.6.25 0.003 0.777 18.11 5.6.24 0.003 0.693 18.20 5.6.23 0.003 0.663 18.19 5.6.22 0.005 0.724 18.01 5.6.21 0.007 0.629 18.11 5.6.20 0.002 0.740 18.03 5.6.19 0.002 0.663 18.22 5.6.18 0.003 0.725 18.01 5.6.17 0.005 0.738 18.29 5.6.16 0.005 0.648 17.86 5.6.15 0.007 0.663 18.29 5.6.14 0.002 0.816 17.93 5.6.13 0.007 0.727 18.20 5.6.12 0.005 0.693 18.25 5.6.11 0.002 0.791 17.96 5.6.10 0.007 0.734 18.14 5.6.9 0.000 0.778 18.30 5.6.8 0.005 0.649 17.71 5.6.7 0.005 0.758 17.97 5.6.6 0.007 0.701 17.76 5.6.5 0.010 0.746 17.85 5.6.4 0.005 0.651 17.63 5.6.3 0.007 0.642 17.85 5.6.2 0.000 0.669 17.76 5.6.1 0.002 0.657 17.90 5.6.0 0.005 0.655 17.81 5.5.38 0.007 0.037 15.95 5.5.37 0.003 0.034 15.84 5.5.36 0.002 0.039 15.85 5.5.35 0.007 0.035 16.06 5.5.34 0.003 0.035 16.33 5.5.33 0.004 0.036 16.38 5.5.32 0.005 0.040 16.04 5.5.31 0.007 0.037 16.02 5.5.30 0.005 0.039 16.14 5.5.29 0.010 0.033 16.25 5.5.28 0.002 0.042 16.07 5.5.27 0.003 0.038 16.29 5.5.26 0.000 0.037 16.04 5.5.25 0.003 0.028 15.97 5.5.24 0.005 0.025 15.65 5.5.23 0.004 0.036 15.78 5.5.22 0.007 0.037 15.76 5.5.21 0.003 0.041 15.85 5.5.20 0.002 0.041 15.64 5.5.19 0.006 0.036 15.76 5.5.18 0.007 0.037 15.76 5.5.17 0.007 0.004 14.24 5.5.16 0.003 0.038 15.77 5.5.15 0.007 0.028 15.86 5.5.14 0.004 0.039 15.88 5.5.13 0.004 0.037 15.75 5.5.12 0.007 0.032 15.63 5.5.11 0.007 0.032 15.71 5.5.10 0.003 0.040 15.58 5.5.9 0.006 0.033 15.75 5.5.8 0.009 0.034 15.72 5.5.7 0.002 0.041 15.81 5.5.6 0.005 0.035 15.60 5.5.5 0.005 0.037 15.73 5.5.4 0.002 0.037 15.77 5.5.3 0.005 0.038 15.74 5.5.2 0.003 0.038 15.54 5.5.1 0.005 0.033 15.66 5.5.0 0.004 0.040 15.71 5.4.45 0.006 0.033 15.58 5.4.44 0.004 0.039 15.58 5.4.43 0.005 0.036 15.57 5.4.42 0.002 0.034 15.54 5.4.41 0.000 0.024 15.39 5.4.40 0.003 0.036 15.31 5.4.39 0.005 0.037 15.39 5.4.38 0.005 0.035 15.38 5.4.37 0.000 0.039 15.31 5.4.36 0.003 0.038 15.31 5.4.35 0.004 0.035 15.28 5.4.34 0.002 0.039 15.41 5.4.33 0.000 0.008 11.61 5.4.32 0.000 0.041 15.31 5.4.31 0.000 0.037 15.38 5.4.30 0.003 0.036 15.32 5.4.29 0.002 0.037 15.37 5.4.28 0.002 0.040 15.42 5.4.27 0.005 0.038 15.34 5.4.26 0.006 0.035 15.34 5.4.25 0.007 0.032 15.38 5.4.24 0.006 0.033 15.37 5.4.23 0.000 0.038 15.29 5.4.22 0.007 0.038 15.32 5.4.21 0.002 0.038 15.30 5.4.20 0.005 0.035 15.38 5.4.19 0.002 0.036 15.27 5.4.18 0.003 0.036 15.29 5.4.17 0.005 0.028 15.36 5.4.16 0.006 0.036 15.30 5.4.15 0.000 0.039 15.40 5.4.14 0.005 0.035 14.05 5.4.13 0.002 0.034 14.13 5.4.12 0.007 0.032 14.12 5.4.11 0.004 0.034 14.07 5.4.10 0.004 0.034 14.16 5.4.9 0.001 0.033 14.05 5.4.8 0.002 0.035 14.11 5.4.7 0.002 0.033 14.06 5.4.6 0.002 0.035 14.04 5.4.5 0.002 0.033 13.98 5.4.4 0.002 0.035 14.05 5.4.3 0.002 0.038 14.03 5.4.2 0.004 0.031 13.99 5.4.1 0.006 0.035 14.07 5.4.0 0.002 0.034 13.73
preferences:dark mode live preview
37.93 ms | 401 KiB | 5 Q