3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace Magnus; class ObjectDispatch { /* This version of object dispatch makes use of yield syntax which is only available from PHP 5.5 onwards. * If support for lower level versions are needed, another version of this dispatcher can be written to eliminate yield syntax. */ public function routeIterator(&$path) { while (!empty($path)) { yield end($path); array_pop($path); /* This prevents having to put back a value in the event of a * readjustment in the dispatch path. * Testing indicates that it's better to do array maninpulation than it is * to implement SplDoublyLinkedList for deque behavior. Likewise, * simply tracking the index is a bit slower and can add complexity * when dealing with reorients/redispatches. */ } } public function __invoke($context, $root) { $log = $context->getLogger(); $path = $context->getRequestPath(); $last = ''; $parent = null; $current = $root; $controllerPrefix = $context->getControllerPrefix(); if ($context->getAppMode() === 'DEBUG' && $log !== null) { $log->addDebug('Starting Object Dispatch', [ 'request' => $context->getRequestURI(), 'path' => var_export($path, true), 'root' => var_export($root, true) ]); } foreach ($this->routeIterator($path) as $chunk) { if ($context->getAppMode() === 'DEBUG' && $log !== null) { $log->addDebug('Beginning dispatch step.', [ 'chunk' => $chunk, 'path' => var_export($path, true), 'current' => var_export($current, true) ]); } if (!is_object($current) || class_exists($controllerPrefix . $current)) { if ($context->getAppMode() === 'DEBUG' && $log !== null) { $log->addDebug('Instantiating current class', [ 'request' => $context->getRequestURI(), 'current' => $current ]); } $resolvedClass = $controllerPrefix . $current; $current = new $resolvedClass($context); } if (is_object($current)) { $parent = $current; } if (in_array($chunk, get_class_methods($parent))) { if ($context->getAppMode() === 'DEBUG' && $log !== null) { $log->addDebug('Found an endpoint', [ 'request' => $context->getRequestURI(), 'isEndpoint' => true, 'parent' => var_export($parent, true), 'handler' => $chunk, 'arguments' => var_export($path, true) ]); } yield array($parent, $chunk, $path, true); } elseif (in_array($chunk, get_object_vars($parent))) { if ($context->getAppMode() === 'DEBUG' && $log !== null) { $log->addDebug('Found a property', [ 'request' => $context->getRequestURI(), 'property' => $chunk, 'parent' => var_export($parent, true) ]); } $current = $parent->chunk; } elseif (method_exists($parent, 'lookup')) { try { list($current, $consumed) = $parent->lookup($path); $chunk = implode('/', $consumed); $path = array_slice($path, 0, count($path) - count($consumed)); } catch (Exception $e) { throw new HTTPNotFound(); } } else { throw new HTTPNotFound(); } yield array(explode('/', $last), $parent, false); $last = $chunk; } if ($context->getAppMode() === 'DEBUG' && $log !== null) { $log->addDebug('No endpoint found', [ 'request' => $context->getRequestURI(), 'current' => var_export($current), 'parent' => var_export($parent) ]); } if (!is_object($current) && class_exists($controllerPrefix . $current)) { $resolvedClass = $controllerPrefix . $current; $current = new $resolvedClass($context); } if (is_callable($current)) { yield array($current, $last, $path, true); } elseif (is_callable($parent)) { yield array($parent, $last, $path, true); } } } class Context { protected $requestURI; protected $requestPath; protected $appMode; protected $logger; protected $controllerPrefix; public function __construct(Array $config) { $this->requestURI = isset($config['requestURI']) ? $config['requestURI'] : '/'; $this->appMode = isset($config['appMode']) ? $config['appMode'] : 'DEVELOPMENT'; $this->logger = isset($config['logger']) ? $config['logger'] : null; $this->controllerPrefix = isset($config['controllerPrefix']) ? $config['controllerPrefix'] : __NAMESPACE__ . '\\'; $this->requestPath = explode('/', str_replace('\\', '/', strtolower($this->requestURI))); if (end($this->requestPath) === '') { array_pop($this->requestPath); } $this->requestPath = array_reverse($this->requestPath); if (end($this->requestPath) === '') { array_pop($this->requestPath); } } public function getRequestURI() { return $this->requestURI; } public function getRequestPath() { return $this->requestPath; } public function getAppMode() { return $this->appMode; } public function getLogger() { return $this->logger; } public function getControllerPrefix() { return $this->controllerPrefix; } } class HTTPNotFound extends \Exception { public function __construct($message, $code = 0, Exception $previous = null) { parent::__construct($message, $code, $previous); } } class ScreenLog { public function __call($methodName, $args) { echo var_export($args, true) . "\n"; } } class RootController { public $home = 'HomeController'; public function __invoke($args = array()) { return "Root controller index"; } } class HomeController { public $home = 'HomeController'; public function __invoke($args = array()) { return "Home controller index"; } } $context = new Context([ 'requestURI' => '/home', 'logger' => new ScreenLog() ]); $dispatch = new ObjectDispatch(); try { foreach ($dispatch($context, 'RootController') as $signal) { list($object, $chunk, $path, $isEndpoint) = $signal; if ($isEndpoint) { if (!empty($chunk)) { echo $object->$chunk($path); } else { echo $object($path); } } } } catch (Exception $e) { echo "Bummer! " . $e->getMessage(); }

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)
8.3.60.0100.00617.00
8.3.50.0090.00616.75
8.3.40.0090.00919.04
8.3.30.0110.00318.97
8.3.20.0040.00420.38
8.3.10.0030.00521.90
8.3.00.0040.00421.98
8.2.180.0090.00617.13
8.2.170.0130.00622.96
8.2.160.0070.00720.55
8.2.150.0080.00024.18
8.2.140.0040.00424.66
8.2.130.0070.00021.03
8.2.120.0080.00026.35
8.2.110.0030.00719.32
8.2.100.0090.00318.05
8.2.90.0080.00019.30
8.2.80.0050.00517.97
8.2.70.0090.00017.75
8.2.60.0050.00318.05
8.2.50.0030.00718.09
8.2.40.0000.00822.33
8.2.30.0040.00419.73
8.2.20.0040.00717.87
8.2.10.0000.00818.32
8.2.00.0000.00818.13
8.1.280.0150.00625.92
8.1.270.0090.00022.08
8.1.260.0080.00028.09
8.1.250.0040.00428.09
8.1.240.0000.00922.23
8.1.230.0060.00617.96
8.1.220.0000.00817.88
8.1.210.0030.00618.77
8.1.200.0090.00017.48
8.1.190.0040.00417.35
8.1.180.0060.00318.10
8.1.170.0070.00718.45
8.1.160.0040.00421.00
8.1.150.0070.00320.76
8.1.140.0000.00819.63
8.1.130.0070.00017.78
8.1.120.0000.00717.63
8.1.110.0000.00717.61
8.1.100.0000.00817.61
8.1.90.0040.00417.48
8.1.80.0020.00517.65
8.1.70.0030.00317.57
8.1.60.0000.00917.71
8.1.50.0030.00617.56
8.1.40.0030.00617.62
8.1.30.0030.00517.66
8.1.20.0040.00417.76
8.1.10.0000.00817.61
8.1.00.0000.00817.54
8.0.300.0030.00918.77
8.0.290.0050.00316.88
8.0.280.0020.00518.60
8.0.270.0040.00417.43
8.0.260.0030.00317.31
8.0.250.0040.00417.03
8.0.240.0040.00417.02
8.0.230.0020.00517.05
8.0.220.0040.00417.06
8.0.210.0040.00417.10
8.0.200.0040.00417.22
8.0.190.0000.00817.20
8.0.180.0000.00717.07
8.0.170.0040.00417.14
8.0.160.0040.00416.98
8.0.150.0000.00717.07
8.0.140.0040.00417.03
8.0.130.0000.00713.52
8.0.120.0040.00416.96
8.0.110.0000.00817.10
8.0.100.0030.00517.00
8.0.90.0040.00416.94
8.0.80.0030.01217.16
8.0.70.0080.00017.09
8.0.60.0000.00817.15
8.0.50.0040.00417.13
8.0.30.0070.00917.09
8.0.20.0120.00917.40
8.0.10.0030.00617.27
8.0.00.0100.01016.88
7.4.330.0000.00616.79
7.4.320.0000.00716.79
7.4.300.0040.00416.75
7.4.290.0090.00016.72
7.4.280.0040.00416.65
7.4.270.0030.00516.59
7.4.260.0070.00016.64
7.4.250.0040.00416.46
7.4.240.0000.00716.70
7.4.230.0000.00716.72
7.4.220.0090.01016.68
7.4.210.0120.00416.69
7.4.200.0040.00416.44
7.4.160.0000.01616.57
7.4.150.0150.00417.40
7.4.140.0120.01017.86
7.4.130.0110.00816.70
7.4.120.0090.00816.67
7.4.110.0110.00716.72
7.4.100.0070.01016.77
7.4.90.0100.00716.72
7.4.80.0090.00919.39
7.4.70.0050.00716.64
7.4.60.0070.01016.66
7.4.50.0080.00516.67
7.4.40.0110.00516.78
7.4.30.0030.01416.57
7.4.00.0040.01315.06
7.3.330.0060.00013.60
7.3.320.0060.00013.50
7.3.310.0030.00516.54
7.3.300.0030.00316.59
7.3.290.0000.00716.53
7.3.280.0090.01016.60
7.3.270.0150.00317.40
7.3.260.0120.00716.49
7.3.250.0100.00816.69
7.3.240.0070.01016.59
7.3.230.0090.00916.48
7.3.210.0110.00716.65
7.3.200.0120.00619.39
7.3.190.0120.00916.61
7.3.180.0130.00716.61
7.3.170.0150.00816.77
7.3.160.0030.01316.87
7.3.120.0080.00915.25
7.3.110.0030.01415.02
7.3.100.0050.01014.61
7.3.90.0110.00814.92
7.3.80.0100.00215.01
7.3.70.0100.00814.91
7.3.60.0060.00614.97
7.3.50.0060.01114.96
7.3.40.0030.01314.96
7.3.30.0040.01015.05
7.3.20.0070.00716.62
7.3.10.0090.00216.58
7.3.00.0070.00716.71
7.2.330.0180.00016.62
7.2.320.0100.00716.85
7.2.310.0080.01316.88
7.2.300.0060.01516.74
7.2.290.0130.00416.66
7.2.250.0080.01215.04
7.2.240.0060.01415.20
7.2.230.0020.01215.15
7.2.220.0050.01015.28
7.2.210.0100.00715.22
7.2.200.0050.01015.18
7.2.190.0070.00715.11
7.2.180.0040.01115.06
7.2.170.0070.01014.95
7.2.60.0060.00916.75
7.2.00.0040.01219.50
7.1.330.0100.00315.81
7.1.320.0080.01015.94
7.1.310.0050.01015.71
7.1.300.0060.00815.79
7.1.290.0020.01215.76
7.1.280.0070.00515.69
7.1.270.0030.00915.62
7.1.260.0030.00615.66
7.1.200.0060.00615.71
7.1.100.0030.01017.87
7.1.70.0060.00617.16
7.1.60.0110.01419.40
7.1.50.0080.00817.08
7.1.00.0070.07322.36
7.0.200.0780.00014.80
7.0.100.0100.08020.18
7.0.90.0200.06020.14
7.0.80.0030.06020.28
7.0.70.0100.07320.01
7.0.60.0000.04720.08
7.0.50.0000.05320.53
7.0.40.0130.03720.07
7.0.30.0030.04320.11
7.0.20.0000.05020.15
7.0.10.0130.03320.00
7.0.00.0000.04320.10
5.6.280.0030.05720.85
5.6.250.0100.03320.57
5.6.240.0070.06320.65
5.6.230.0070.03720.65
5.6.220.0070.04320.63
5.6.210.0070.06020.82
5.6.200.0130.03021.08
5.6.190.0000.04720.99
5.6.180.0030.06021.11
5.6.170.0170.03321.05
5.6.160.0100.06721.05
5.6.150.0030.06721.11
5.6.140.0030.07321.09
5.6.130.0100.08020.98
5.6.120.0030.05021.12
5.6.110.0030.08321.17
5.6.100.0030.07721.14
5.6.90.0070.08321.10
5.6.80.0070.07720.57
5.6.70.0100.07020.39
5.6.60.0130.07020.50
5.6.50.0130.07020.40
5.6.40.0070.07320.50
5.6.30.0070.08020.51
5.6.20.0100.08020.54
5.6.10.0030.08320.36
5.6.00.0200.06720.37
5.5.380.0130.03020.45
5.5.370.0030.06720.49
5.5.360.0000.05720.48
5.5.350.0000.04320.49
5.5.340.0070.04720.98
5.5.330.0030.06720.86
5.5.320.0030.04020.88
5.5.310.0030.07320.97
5.5.300.0230.06320.85
5.5.290.0030.08020.89
5.5.280.0070.08320.89
5.5.270.0030.08720.84
5.5.260.0130.07320.97
5.5.250.0000.09020.77
5.5.240.0170.07020.24
5.5.230.0030.08020.29
5.5.220.0100.07020.38
5.5.210.0170.07020.21
5.5.200.0100.07320.32
5.5.190.0030.07720.34
5.5.180.0030.07720.29
5.5.160.0130.04720.15
5.5.150.0070.08020.19
5.5.140.0030.08020.33
5.5.130.0130.07720.21
5.5.120.0130.07020.22
5.5.110.0130.07020.25
5.5.100.0000.06320.15
5.5.90.0200.06020.16
5.5.80.0070.05020.22
5.5.70.0070.08020.12
5.5.60.0070.07720.09
5.5.50.0030.08020.16
5.5.40.0070.08020.17
5.5.30.0030.07020.11
5.5.20.0100.07320.13
5.5.10.0070.07720.18
5.5.00.0100.07320.13

preferences:
46.96 ms | 400 KiB | 5 Q