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->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";

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.0030.30916.84
7.4.00.0100.26015.80
7.3.130.0130.29616.69
7.3.120.0050.23615.96
7.3.110.0180.29015.95
7.3.100.0050.23415.70
7.3.90.0030.23115.70
7.3.80.0050.23615.97
7.3.70.0080.20015.88
7.3.60.0030.25015.95
7.3.50.0070.21915.79
7.3.40.0050.25315.86
7.3.30.0070.26315.72
7.3.20.0030.22917.50
7.3.10.0060.21517.06
7.3.00.0070.20717.25
7.2.260.0100.28416.97
7.2.250.0070.29715.88
7.2.240.0050.29315.96
7.2.230.0080.29416.18
7.2.220.0050.27016.04
7.2.210.0100.23116.13
7.2.200.0030.27816.09
7.2.190.0050.27216.06
7.2.180.0080.29216.04
7.2.170.0030.26416.10
7.2.160.0070.33716.78
7.2.150.0030.25318.39
7.2.140.0000.23018.48
7.2.130.0030.28817.55
7.2.120.0050.27017.61
7.2.110.0030.27317.46
7.2.100.0080.25717.65
7.2.90.0100.25717.62
7.2.80.0070.26817.66
7.2.70.0050.23717.69
7.2.60.0070.27517.88
7.2.50.0070.23817.61
7.2.40.0070.30117.62
7.2.30.0040.23317.65
7.2.20.0050.27917.68
7.2.10.0030.26517.87
7.2.00.0070.24218.24
7.1.330.0070.35016.56
7.1.320.0030.34716.57
7.1.310.0050.32516.52
7.1.300.0070.34616.47
7.1.290.0020.32116.60
7.1.280.0030.34916.68
7.1.270.0070.32116.57
7.1.260.0020.34916.49
7.1.250.0120.34716.39
7.1.240.0030.33317.32
7.1.230.0070.39217.26
7.1.220.0070.35217.32
7.1.210.0030.31217.33
7.1.200.0100.32317.35
7.1.190.0070.31917.37
7.1.180.0070.30617.33
7.1.170.0100.34217.50
7.1.160.0100.40717.21
7.1.150.0030.34517.31
7.1.140.0030.39317.52
7.1.130.0100.33217.46
7.1.120.0070.36017.22
7.1.110.0000.36717.47
7.1.100.0000.43417.48
7.1.90.0070.32217.42
7.1.80.0030.34517.29
7.1.70.0020.25217.17
7.1.60.0100.21018.36
7.1.50.0070.30617.26
7.1.40.0030.40817.40
7.1.30.0070.36017.42
7.1.20.0070.28317.31
7.1.10.0000.32317.38
7.1.00.0030.29319.79
7.0.330.0030.35917.18
7.0.320.0070.32816.87
7.0.310.0100.38717.20
7.0.300.0070.46916.77
7.0.290.0030.43317.11
7.0.280.0070.42916.98
7.0.270.0000.35717.18
7.0.260.0030.35916.96
7.0.250.0000.34017.20
7.0.240.0100.35416.96
7.0.230.0070.32917.09
7.0.220.0030.32517.22
7.0.210.0030.36417.14
7.0.200.0080.31416.85
7.0.190.0030.42817.00
7.0.180.0070.35417.02
7.0.170.0030.42617.03
7.0.160.0070.36117.04
7.0.150.0100.34517.09
7.0.140.0070.37719.48
7.0.130.0000.49617.09
7.0.120.0030.35717.15
7.0.110.0070.33917.09
7.0.100.0030.35718.60
7.0.90.0180.29818.59
7.0.80.0150.28418.59
7.0.70.0070.33418.60
7.0.60.0130.25618.50
7.0.50.0020.36218.69
7.0.40.0070.29917.53
7.0.30.0030.38817.52
7.0.20.0100.29017.61
7.0.10.0070.29117.55
7.0.00.0050.35717.57
5.6.400.0000.71216.12
5.6.390.0030.71816.35
5.6.380.0100.79116.25
5.6.370.0030.71016.21
5.6.360.0000.78715.77
5.6.350.0100.75616.20
5.6.340.0030.72516.48
5.6.330.0100.86716.47
5.6.320.0130.82316.00
5.6.310.0030.75616.23
5.6.300.0100.82616.12
5.6.290.0030.86816.07
5.6.280.0050.62118.64
5.6.270.0100.77015.96
5.6.260.0000.73216.45
5.6.250.0050.57518.40
5.6.240.0030.56318.40
5.6.230.0050.58718.42
5.6.220.0070.57518.45
5.6.210.0100.55718.49
5.6.200.0070.66018.64
5.6.190.0080.59018.68
5.6.180.0150.65418.71
5.6.170.0070.62618.77
5.6.160.0120.60818.69
5.6.150.0070.64918.60
5.6.140.0070.55718.59
5.6.130.0030.70018.76
5.6.120.0180.58218.76
5.6.110.0080.66518.60
5.6.100.0570.57818.67
5.6.90.0080.62118.64
5.6.80.0070.56418.32
5.6.70.0030.58418.29
5.6.60.0030.65618.20
5.6.50.0100.57318.30
5.6.40.0100.65418.41
5.6.30.0070.56318.43
5.6.20.0100.57018.47
5.6.10.0100.55918.35
5.6.00.0070.58318.24
5.5.380.0100.02718.08
5.5.370.0040.04518.08
5.5.360.0100.02517.93
5.5.350.0080.02818.08
5.5.340.0090.03418.32
5.5.330.0060.03118.30
5.5.320.0070.04618.20
5.5.310.0090.04518.20
5.5.300.0070.03318.09
5.5.290.0060.03818.35
5.5.280.0050.02718.33
5.5.270.0080.04518.36
5.5.260.0050.03518.29
5.5.250.0050.04318.15
5.5.240.0030.02418.01
5.5.230.0070.04217.93
5.5.220.0090.03417.95
5.5.210.0070.03617.97
5.5.200.0030.04217.90
5.5.190.0080.03517.89
5.5.180.0060.02017.97
5.5.170.0090.00315.64
5.5.160.0040.02217.88
5.5.150.0070.02017.94
5.5.140.0030.02517.81
5.5.130.0020.02717.95
5.5.120.0010.02317.82
5.5.110.0070.02417.98
5.5.100.0050.02517.89
5.5.90.0020.02217.86
5.5.80.0060.04417.75
5.5.70.0080.01817.88
5.5.60.0030.03117.91
5.5.50.0050.03917.90
5.5.40.0090.02617.91
5.5.30.0050.02217.84
5.5.20.0030.02817.78
5.5.10.0070.02217.86
5.5.00.0030.02717.75
5.4.450.0080.03615.82
5.4.440.0030.04016.02
5.4.430.0120.01916.02
5.4.420.0130.03315.90
5.4.410.0100.03715.67
5.4.400.0050.03715.71
5.4.390.0040.02715.70
5.4.380.0050.04215.87
5.4.370.0050.02315.64
5.4.360.0060.03315.79
5.4.350.0050.04115.79
5.4.340.0050.04115.83
5.4.330.0000.00912.39
5.4.320.0020.02515.54
5.4.310.0030.02115.76
5.4.300.0030.02415.76
5.4.290.0030.01815.72
5.4.280.0010.02015.78
5.4.270.0060.02015.73
5.4.260.0020.01815.59
5.4.250.0000.03515.77
5.4.240.0040.03515.77
5.4.230.0100.01315.61
5.4.220.0080.04515.80
5.4.210.0020.02215.60
5.4.200.0030.02315.70
5.4.190.0070.02015.72
5.4.180.0070.02015.66
5.4.170.0030.02415.67
5.4.160.0030.02915.70
5.4.150.0030.02015.65
5.4.140.0060.02114.44
5.4.130.0010.02114.37
5.4.120.0050.01714.41
5.4.110.0030.01814.55
5.4.100.0070.01614.37
5.4.90.0030.02114.30
5.4.80.0060.01614.26
5.4.70.0020.02114.39
5.4.60.0030.02214.41
5.4.50.0000.02814.45
5.4.40.0000.02014.42
5.4.30.0080.01514.51
5.4.20.0000.02114.49
5.4.10.0030.01714.31
5.4.00.0020.02214.20

preferences:
45.13 ms | 400 KiB | 5 Q