3v4l.org

run code in 300+ PHP versions simultaneously
<?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";

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).

VersionSystem time (s)User time (s)Memory (MiB)
7.4.10.0130.24515.07
7.4.00.0100.32415.30
7.3.130.0070.25115.05
7.3.120.0070.33414.72
7.3.110.0080.29114.86
7.3.100.0070.24515.20
7.3.90.0020.22215.09
7.3.80.0030.22614.98
7.3.70.0020.24215.00
7.3.60.0050.24015.16
7.3.50.0030.21915.15
7.3.40.0080.28115.09
7.3.30.0100.21614.84
7.3.20.0050.21516.70
7.3.10.0030.23016.72
7.3.00.0090.23016.63
7.2.260.0030.27615.42
7.2.250.0020.39215.32
7.2.240.0050.31915.39
7.2.230.0030.31115.15
7.2.220.0050.32415.46
7.2.210.0000.33215.19
7.2.200.0080.24915.15
7.2.190.0080.31415.08
7.2.180.0050.33515.20
7.2.170.0050.27115.31
7.2.160.0000.39315.34
7.2.150.0100.29917.00
7.2.140.0030.27216.91
7.2.130.0050.30916.85
7.2.120.0100.30116.89
7.2.110.0050.29416.82
7.2.100.0050.25116.95
7.2.90.0030.30116.96
7.2.80.0080.28816.93
7.2.70.0080.31716.83
7.2.60.0070.30016.78
7.2.50.0030.26016.92
7.2.40.0030.27716.96
7.2.30.0070.32317.10
7.2.20.0080.26116.90
7.2.10.0120.30316.88
7.2.00.0050.24417.67
7.1.330.0030.35915.79
7.1.320.0070.40915.79
7.1.310.0050.36815.86
7.1.300.0030.38315.80
7.1.290.0070.39515.77
7.1.280.0030.41015.75
7.1.270.0070.37315.68
7.1.260.0080.37115.81
7.1.250.0030.40015.96
7.1.240.0030.38515.86
7.1.230.0030.36415.56
7.1.220.0000.36215.99
7.1.210.0100.32615.85
7.1.200.0070.37715.96
7.1.190.0070.43815.91
7.1.180.0070.41615.97
7.1.170.0070.34415.80
7.1.160.0070.35815.77
7.1.150.0030.32115.93
7.1.140.0190.34415.91
7.1.130.0070.46415.94
7.1.120.0030.38715.84
7.1.110.0100.42016.00
7.1.100.0030.45315.95
7.1.90.0000.38515.73
7.1.80.0070.42715.93
7.1.70.0050.31416.56
7.1.60.0080.31917.71
7.1.50.0080.29816.35
7.1.40.0100.42415.95
7.1.30.0030.38515.76
7.1.20.0030.37615.92
7.1.10.0030.46815.81
7.1.00.0080.33519.14
7.0.330.0000.37915.55
7.0.320.0000.41615.38
7.0.310.0030.40815.41
7.0.300.0000.39415.48
7.0.290.0000.46915.18
7.0.280.0070.45815.23
7.0.270.0030.42215.28
7.0.260.0030.45715.47
7.0.250.0030.38315.52
7.0.240.0030.52115.33
7.0.230.0060.42415.22
7.0.220.0070.54315.45
7.0.210.0070.38215.59
7.0.200.0070.33716.24
7.0.190.0030.43315.24
7.0.180.0070.35815.22
7.0.170.0090.50115.48
7.0.160.0030.41515.34
7.0.150.0030.44015.50
7.0.140.0020.46218.82
7.0.130.0130.48215.21
7.0.120.0030.37118.67
7.0.110.0100.34618.71
7.0.100.0030.42518.82
7.0.90.0050.35918.88
7.0.80.0050.42918.75
7.0.70.0030.37818.79
7.0.60.0000.36818.63
7.0.50.0020.44019.00
7.0.40.0030.34817.72
7.0.30.0070.37317.92
7.0.20.0030.34717.73
7.0.10.0020.39517.71
7.0.00.0070.36817.84
5.6.400.0070.71014.86
5.6.390.0070.92315.12
5.6.380.0030.80015.06
5.6.370.0000.84414.95
5.6.360.0000.85515.06
5.6.350.0070.89315.18
5.6.340.0070.84414.76
5.6.330.0070.96815.09
5.6.320.0000.84414.79
5.6.310.0030.75014.93
5.6.300.0100.70615.00
5.6.290.0070.88814.73
5.6.280.0050.72518.20
5.6.270.0100.70515.05
5.6.260.0050.74518.23
5.6.250.0030.77718.11
5.6.240.0030.69318.20
5.6.230.0030.66318.19
5.6.220.0050.72418.01
5.6.210.0070.62918.11
5.6.200.0020.74018.03
5.6.190.0020.66318.22
5.6.180.0030.72518.01
5.6.170.0050.73818.29
5.6.160.0050.64817.86
5.6.150.0070.66318.29
5.6.140.0020.81617.93
5.6.130.0070.72718.20
5.6.120.0050.69318.25
5.6.110.0020.79117.96
5.6.100.0070.73418.14
5.6.90.0000.77818.30
5.6.80.0050.64917.71
5.6.70.0050.75817.97
5.6.60.0070.70117.76
5.6.50.0100.74617.85
5.6.40.0050.65117.63
5.6.30.0070.64217.85
5.6.20.0000.66917.76
5.6.10.0020.65717.90
5.6.00.0050.65517.81
5.5.380.0070.03715.95
5.5.370.0030.03415.84
5.5.360.0020.03915.85
5.5.350.0070.03516.06
5.5.340.0030.03516.33
5.5.330.0040.03616.38
5.5.320.0050.04016.04
5.5.310.0070.03716.02
5.5.300.0050.03916.14
5.5.290.0100.03316.25
5.5.280.0020.04216.07
5.5.270.0030.03816.29
5.5.260.0000.03716.04
5.5.250.0030.02815.97
5.5.240.0050.02515.65
5.5.230.0040.03615.78
5.5.220.0070.03715.76
5.5.210.0030.04115.85
5.5.200.0020.04115.64
5.5.190.0060.03615.76
5.5.180.0070.03715.76
5.5.170.0070.00414.24
5.5.160.0030.03815.77
5.5.150.0070.02815.86
5.5.140.0040.03915.88
5.5.130.0040.03715.75
5.5.120.0070.03215.63
5.5.110.0070.03215.71
5.5.100.0030.04015.58
5.5.90.0060.03315.75
5.5.80.0090.03415.72
5.5.70.0020.04115.81
5.5.60.0050.03515.60
5.5.50.0050.03715.73
5.5.40.0020.03715.77
5.5.30.0050.03815.74
5.5.20.0030.03815.54
5.5.10.0050.03315.66
5.5.00.0040.04015.71
5.4.450.0060.03315.58
5.4.440.0040.03915.58
5.4.430.0050.03615.57
5.4.420.0020.03415.54
5.4.410.0000.02415.39
5.4.400.0030.03615.31
5.4.390.0050.03715.39
5.4.380.0050.03515.38
5.4.370.0000.03915.31
5.4.360.0030.03815.31
5.4.350.0040.03515.28
5.4.340.0020.03915.41
5.4.330.0000.00811.61
5.4.320.0000.04115.31
5.4.310.0000.03715.38
5.4.300.0030.03615.32
5.4.290.0020.03715.37
5.4.280.0020.04015.42
5.4.270.0050.03815.34
5.4.260.0060.03515.34
5.4.250.0070.03215.38
5.4.240.0060.03315.37
5.4.230.0000.03815.29
5.4.220.0070.03815.32
5.4.210.0020.03815.30
5.4.200.0050.03515.38
5.4.190.0020.03615.27
5.4.180.0030.03615.29
5.4.170.0050.02815.36
5.4.160.0060.03615.30
5.4.150.0000.03915.40
5.4.140.0050.03514.05
5.4.130.0020.03414.13
5.4.120.0070.03214.12
5.4.110.0040.03414.07
5.4.100.0040.03414.16
5.4.90.0010.03314.05
5.4.80.0020.03514.11
5.4.70.0020.03314.06
5.4.60.0020.03514.04
5.4.50.0020.03313.98
5.4.40.0020.03514.05
5.4.30.0020.03814.03
5.4.20.0040.03113.99
5.4.10.0060.03514.07
5.4.00.0020.03413.73

preferences:
37.93 ms | 401 KiB | 5 Q