3v4l.org

run code in 300+ PHP versions simultaneously
<?php /** * JAVA Autoboxing (part of Lotos Framework) * * Copyright (c) 2005-2010 Artur Graniszewski (aargoth@boo.pl) * All rights reserved. * * @category Library * @package Lotos * @subpackage DataTypes * @copyright Copyright (c) 2005-2010 Artur Graniszewski (aargoth@boo.pl) * @license GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 * @version $Id$ */ final class VariablesManager { /** * Security checks * * @var bool */ private static $initFinished = false; /** * Minimal string size to cache. * * @var integer */ private static $minStringSize; /** * Number of the most current pointer. * * @var int */ private static $counter; public static $memory = array(); /** * Internal pool * array($privateInternId => * array( * [0] - Variable value * [1] - Number of different instances sharing this variable * [2] - Variable length * [3] - Public Intern id * ) * ) */ private static $internPool = array(); /** * Array of internal pools' names. * * @var string[] */ private static $internPoolId = array(); /** * Number of the most current internal pool id. * * @var int */ private static $internPoolCounter = 1; /** * Initializes new variable of the given type and returns C-like pointer to it. * * It allows us to do variable type enforcing and silent object casting * * @param String Data type * @return mixed Pointer to variable * @todo change to array pool? */ public static function & getNewPointer($dataType) { do { ++self::$counter; $name = 'vm_var_'.self::$counter; } while (isset(VariablesManager::$memory[$name])); VariablesManager::$memory[$name] = $dataType; if(is_object($dataType) && in_array('setPointer', get_class_methods($dataType))) { $dataType->setPointer($name); } return VariablesManager::$memory[$name]; } /** * Returns intern reference of the existing string or creates and returns new one if it doesn't exist. * * @param string Simple type string * @param string Internal pool id reserved for given string * @param integer String length if calculated in a cache or null otherwise * @return string String reference or null if string was invalid */ public static function & getIntern(& $string, & $internId, & $length = null) { if(!$length) { $length = strlen($string); } // cache only big strings if($string === '' || !isset($string[self::$minStringSize]) || strlen($string) < self::$minStringSize) { $internId = 0; return $string; } $intern = & self::$internPool[$string]; if(isset($intern)) { // variable exists in cache: // increase the 'variable in use' counter by one ++$intern[1]; // set flags, etc $length = $intern[2]; $internId = $intern[3]; return $intern[0]; } else { $internId = self::$internPoolCounter++; self::$internPool[$string] = array(0 => & $string, 1 => 1, 2 => & $length, 3 => $internId); self::$internPoolId[$internId] = & $string; return $string; } } /** * Unsets internal pool entity or decreases it's counter by one if variable is still in use by other instances. * * @param String intern */ public static function unsetIntern($internId) { // is PHP shutting down? if it is, then avoid unnecesary cleaning, PHP will do it automatically if($internId === 0) { return; } $id = $internId; $intern = & self::$internPool[self::$internPoolId[$internId]]; if(isset($intern)) { --$intern[1]; if($intern[1] === 0) { unset(self::$internPool[self::$internPoolId[$internId]]); unset(self::$internPoolId[$internId]); } } } /** * Initialises LOTOS Variables Manager. * @access public * @static * @param integer Minimal variable size needed to put it in cache * @return void */ public static function init(& $minStringSize = 2) { self::$minStringSize = & $minStringSize; if(self::$initFinished) { return null; } self::$initFinished = true; return new self(); } /** * LOTOS VM constructor. * * @return void */ private function __construct() { } /** * LOTOS VM destructor (not used). * * @return void */ public function __destruct() { } /** * Returns LOTOS VM statistics. * * @return mixed[] Array containing VM statistics. */ public function getPoolUsage() { $len = 0; $shared = 0; $real = 0; $count = 0; foreach(self::$internPool as $var) { $len = strlen($var[0]); $real += $len; $shared += $len * $var[1]; $count += $var[1]; } $segments = count(self::$internPool); $ret = array('count' => $count, 'segments' => $segments, 'ratio' => ($segments > 0 ? ($count / $segments) * 100 : 0), 'memory' => array('real' => $real, 'shared' => $shared, 'ratio' => $real > 0 ? ($shared/$real) * 100 : 0)); return $ret; } } /** * AutoBoxedObject * * Every class needs to inherit this class in order to use PHP autoboxing. * @author Artur Graniszewski */ abstract class AutoBoxedObject { /** * C-like variable pointer. * * @var mixed */ protected $ref; /** * Internal ID used by caching mechanism (but not used frequently). * * @var int */ protected $internId; /** * Public constructor * * @return AutoBoxedObject */ public function __construct() { } /** * Destructor used to datatype enforcing and final cleanups. * * @return void */ public function __destruct() { if($this->ref === null) { return; } if(VariablesManager::$memory[$this->ref] instanceof self) { VariablesManager::$memory[$this->ref]->setPointer($this->ref); } else if(is_scalar(VariablesManager::$memory[$this->ref])){ $val = VariablesManager::$memory[$this->ref]; $class = get_class($this);; VariablesManager::$memory[$this->ref] = new $class($val); VariablesManager::$memory[$this->ref]->setPointer($this->ref); } } /** * Sets C-like pointer for this object. * * @param mixed $name */ public function setPointer($name) { $this->ref = $name; } /** * Returns internal ID of this object. * * @return mixed */ public function getIntern() { return $this->internId; } /** * Returns string representation of this object. * * @return string */ public function toString() { return $this->__toString(); } } class PrimitiveTypeWrapper extends AutoBoxedObject { protected $value = null; protected $allowedCasting = array(); public function __toString() { // NOTE: this must be a string, PHP forbids returning different type of variables in __toString() methods. return "{$this->value}"; } /** * Converts this variable to Integer object. * * @return Integer */ public function & toInt() { $x = & integer((int)$this->value); return $x; } /** * Converts this variable to Float object. * * @return Float */ public function & toFloat() { $x = & float((int)$this->value); return $x; } /** * Converts this variable to String object. * * @return String */ public function & toString() { $x = & string((string)$this->value); return $x; } /** * Destructor used to datatype enforcing and final cleanups. * * This time we are overwritting default Lotos VariablesManager behaviour and use * strong data type enforcing * * @return void */ public function __destruct() { if($this->ref === null) { return; } if(is_object(VariablesManager::$memory[$this->ref]) && get_class(VariablesManager::$memory[$this->ref]) === get_class($this) && in_array('setPointer', get_class_methods(VariablesManager::$memory[$this->ref]))) { VariablesManager::$memory[$this->ref]->setPointer($this->ref); } else if(is_scalar(VariablesManager::$memory[$this->ref])){ $val = VariablesManager::$memory[$this->ref]; $class = get_class($this); VariablesManager::$memory[$this->ref] = new $class($val); VariablesManager::$memory[$this->ref]->setPointer($this->ref); } else if(is_object(VariablesManager::$memory[$this->ref])) { foreach($this->allowedCasting as $dataType) { if(is_a(VariablesManager::$memory[$this->ref], $dataType)) { return; } } throw new Exception('Cannot cast '.get_class(VariablesManager::$memory[$this->ref]).' data type to '.get_class($this).'!'); } } } /** * Example class. * * Note: in order to use AutoBoxing, your class need to extend "AutoBoxedObject" class. */ class String extends PrimitiveTypeWrapper { protected $allowedCasting = array('Integer', 'Double', 'Float', 'Bool', 'Number'); public function __construct($value) { // TYPE ENFORCING if($value && !is_scalar ($value)) { throw new Exception('The new value is not a scalar!!!'); } $this->value = (string)$value; } public function getHex() { $x = strtoupper(dechex($this->value)); $y = ceil(strlen($x) / 2); return str_pad($x, $y * 2, '0', STR_PAD_LEFT); } } /** * Example class. * * Note: in order to use AutoBoxing, your class need to extend "AutoBoxedObject" class. */ class Bool extends PrimitiveTypeWrapper { public function __construct($value) { // TYPE ENFORCING if($value && !is_bool ($value)) { throw new Exception('The new value is not a boolean type!!!'); } $this->value = (bool)$value; } /** * Converts this variable to String object. * * @return String */ public function & toString() { $x = & string($this->value === true ? 'true' : ($this->value === false ? 'false' : 'null')); return $x; } } /** * Example class. * * Note: in order to use AutoBoxing, your class need to extend "AutoBoxedObject" class. */ class Integer extends PrimitiveTypeWrapper { public function __construct($value) { // TYPE ENFORCING if($value && !is_int ($value) && !is_float($value)) { throw new Exception('The new value cannot be cast to integer!!!'); } $this->value = (int)$value; } public function toHex($useX = false) { $x = strtoupper(dechex($this->value)); $y = ceil(strlen($x) / 2); return ($useX ? '0x': '').str_pad($x, $y * 2, '0', STR_PAD_LEFT); } } /** * Example class. * * Note: in order to use AutoBoxing, your class need to extend "AutoBoxedObject" class. */ class Number extends PrimitiveTypeWrapper { protected $allowedCasting = array('Integer', 'Double', 'Float'); public function __construct($value) { // TYPE ENFORCING if($value && !is_int ($value) && !is_float($value) && !is_double($value)) { throw new Exception('The new value cannot be cast to integer!!!'); } $this->value = (double)$value; } public function toHex($useX = false) { $x = strtoupper(dechex($this->value)); $y = ceil(strlen($x) / 2); return ($useX ? '0x': '').str_pad($x, $y * 2, '0', STR_PAD_LEFT); } } /** * Example class. * * Note: in order to use AutoBoxing, your class need to extend "AutoBoxedObject" class. */ class Float extends PrimitiveTypeWrapper { protected $allowedCasting = array('Double'); public function __construct($value) { // TYPE ENFORCING if($value && !is_int ($value) && !is_float($value)) { throw new Exception('The new value cannot be cast to float!!!'); } $this->value = (float)$value; } } /** * Example class. * * Note: in order to use AutoBoxing, your class need to extend "AutoBoxedObject" class. */ class Double extends Float { } /** * Initializes a newly created Float object. * @return Float created String object */ function & float($value = null) { $type = ucfirst(strtolower(__FUNCTION__)); $x = & VariablesManager::getNewPointer(new $type($value)); return $x; } /** * Initializes a newly created Float object. * @return Float created String object */ function & double($value = null) { $type = ucfirst(strtolower(__FUNCTION__)); $x = & VariablesManager::getNewPointer(new $type($value)); return $x; } /** * Initializes a newly created Integer object. * @return Integer created String object */ function & integer($value = null) { $type = ucfirst(strtolower(__FUNCTION__)); $x = & VariablesManager::getNewPointer(new $type($value)); return $x; } /** * Initializes a newly created String object. * @return String created String object */ function & string($value = null) { $type = ucfirst(strtolower(__FUNCTION__)); $x = & VariablesManager::getNewPointer(new $type($value)); return $x; } /** * Initializes a newly created Bool object. * @return Bool created String object */ function & bool($value = null) { $type = ucfirst(strtolower(__FUNCTION__)); $x = & VariablesManager::getNewPointer(new $type($value)); return $x; } /** * Initializes a newly created Bool object. * @return Bool created String object */ function & number($value = null) { $type = ucfirst(strtolower(__FUNCTION__)); $x = & VariablesManager::getNewPointer(new $type($value)); return $x; } // Lotos VM auto init (taken from the Lotos frameworks' autostart and executed manually below) VariablesManager::init(); // --------------------------------------------------------------------------- // simple autoboxing checks $x = & integer(12); $x = "$x" + 1; echo $x.' => '.$x->toHex(true)."<br />"; $x = & float(12.12); $x = "$x" * 2; echo $x.' => '.$x->toInt()."<br />"; // --------------------------------------------------------------------------- // with strong data type enforcing set integer value of 12 to the boolean variable $x = & bool(); $x = true; try { $x = 12; } catch (Exception $e) { echo "Exception catched: ".$e->getMessage().' (code: '.$e->getCode().')<br />'; } // --------------------------------------------------------------------------- // with strong data type enforcing we cannot cast String ($y) to Number($x): $x = & number(); $x = 12.33; $y = & string("ok"); try { $x = $y; } catch(Exception $e) { echo "Exception catched: ".$e->getMessage().' (code: '.$e->getCode().')<br />'; } // --------------------------------------------------------------------------- // but we can cast Number to Double, Float, etc. $x = & number(); $x = 12.33; $y = & double(3.33); $x = $y; echo $x.' => '.$x->toString()."<br />";

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)
5.6.280.0000.07721.05
5.6.250.0230.07320.75
5.6.240.0030.08720.77
5.6.230.0170.05720.70
5.6.220.0170.07320.71
5.6.210.0030.05020.89
5.6.200.0130.07321.08
5.6.190.0170.04021.08
5.6.180.0030.06021.12
5.6.170.0130.06721.19
5.6.160.0100.04721.13
5.6.150.0130.06321.19
5.6.140.0030.08321.20
5.6.130.0070.05321.17
5.6.120.0070.09321.12
5.6.110.0000.05721.14
5.6.100.0170.07721.25
5.6.90.0070.08021.05
5.6.80.0000.05020.45
5.6.70.0070.08020.46
5.6.60.0000.08320.44
5.6.50.0130.05020.59
5.6.40.0030.07720.41
5.6.30.0100.08020.57
5.6.20.0030.07320.42
5.6.10.0130.07720.50
5.6.00.0170.07720.49
5.5.380.0070.05320.55
5.5.370.0130.07020.58
5.5.360.0170.07720.51
5.5.350.0130.07020.56
5.5.340.0070.05020.89
5.5.330.0070.08321.01
5.5.320.0070.07720.93
5.5.310.0030.08321.00
5.5.300.0130.08020.93
5.5.290.0000.05721.02
5.5.280.0070.05321.01
5.5.270.0000.07321.04
5.5.260.0100.08020.98
5.5.250.0100.07720.70
5.5.240.0100.08020.30
5.5.230.0030.07720.44
5.5.220.0200.06720.34
5.5.210.0030.08720.38
5.5.200.0030.08720.42
5.5.190.0100.06720.40
5.5.180.0100.06320.29
5.5.160.0130.07020.30
5.5.150.0070.05020.36
5.5.140.0130.06720.25
5.5.130.0030.06020.39
5.5.120.0170.07320.30
5.5.110.0130.07320.39
5.5.100.0130.07320.25
5.5.90.0070.08020.28
5.5.80.0030.08320.20
5.5.70.0030.07320.13
5.5.60.0130.06020.22
5.5.50.0070.07720.28
5.5.40.0100.07020.21
5.5.30.0200.07020.22
5.5.20.0030.07320.25
5.5.10.0030.06720.09
5.5.00.0100.05720.23
5.4.450.0130.07319.47
5.4.440.0130.07319.49
5.4.430.0200.04019.56
5.4.420.0030.08019.59
5.4.410.0070.07319.46
5.4.400.0030.08319.09
5.4.390.0000.08319.11
5.4.380.0070.08319.16
5.4.370.0070.07719.23
5.4.360.0030.08319.20
5.4.350.0070.07019.11
5.4.340.0100.07719.26
5.4.320.0170.06019.09
5.4.310.0130.04718.92
5.4.300.0100.04019.13
5.4.290.0070.06019.23
5.4.280.0200.06319.09
5.4.270.0030.04319.11
5.4.260.0100.07719.09
5.4.250.0070.04319.12
5.4.240.0030.07719.12
5.4.230.0130.07019.08
5.4.220.0100.07719.08
5.4.210.0070.07318.92
5.4.200.0000.08719.27
5.4.190.0030.07319.09
5.4.180.0170.06719.21
5.4.170.0030.04719.10
5.4.160.0100.07019.07
5.4.150.0100.07019.16
5.4.140.0030.08016.51
5.4.130.0100.03316.51
5.4.120.0100.06016.34
5.4.110.0100.07316.38
5.4.100.0070.04016.56
5.4.90.0070.04016.43
5.4.80.0100.06716.55
5.4.70.0030.07716.56
5.4.60.0100.06716.36
5.4.50.0170.06316.45
5.4.40.0100.07316.39
5.4.30.0070.06016.44
5.4.20.0030.07016.50
5.4.10.0070.06716.57
5.4.00.0000.07015.74
5.3.290.0070.07714.91
5.3.280.0070.03714.83
5.3.270.0100.06714.87
5.3.260.0070.08014.92
5.3.250.0030.07314.71
5.3.240.0130.06714.75
5.3.230.0170.06714.75
5.3.220.0000.05314.83
5.3.210.0070.07714.84
5.3.200.0130.03714.81
5.3.190.0070.07714.72
5.3.180.0100.07314.75
5.3.170.0070.05314.77
5.3.160.0070.04314.72
5.3.150.0170.06714.87
5.3.140.0070.06714.73
5.3.130.0070.06714.79
5.3.120.0000.08314.88
5.3.110.0100.03714.74
5.3.100.0100.06314.18
5.3.90.0030.07714.25
5.3.80.0100.06314.32
5.3.70.0100.05314.22
5.3.60.0070.07014.16
5.3.50.0000.07714.20
5.3.40.0000.08714.23
5.3.30.0000.08014.02
5.3.20.0000.07713.90
5.3.10.0070.03713.89
5.3.00.0100.07013.74
5.2.170.0030.06711.32
5.2.160.0030.05711.24
5.2.150.0030.06311.27
5.2.140.0070.05011.26
5.2.130.0000.06311.18
5.2.120.0100.03011.36
5.2.110.0030.06311.36
5.2.100.0030.06311.36
5.2.90.0000.05311.38
5.2.80.0030.06011.20
5.2.70.0070.03311.22
5.2.60.0130.05311.15
5.2.50.0030.03711.28
5.2.40.0030.06311.25
5.2.30.0000.04011.12
5.2.20.0030.05011.02
5.2.10.0070.05010.91
5.2.00.0100.05710.93
5.1.60.0070.05310.30
5.1.50.0030.05310.19
5.1.40.0030.05010.26
5.1.30.0000.06010.62
5.1.20.0070.03310.47
5.1.10.0000.04310.27
5.1.00.0070.05710.33
5.0.50.0030.0478.82
5.0.40.0070.0408.68
5.0.30.0000.0678.68
5.0.20.0000.0438.68
5.0.10.0070.0238.68
5.0.00.0000.0638.68
4.4.90.0030.0308.68
4.4.80.0030.0338.68
4.4.70.0030.0208.68
4.4.60.0070.0308.68
4.4.50.0000.0208.68
4.4.40.0030.0508.68
4.4.30.0000.0378.68
4.4.20.0100.0238.68
4.4.10.0070.0208.68
4.4.00.0030.0408.68
4.3.110.0030.0338.68
4.3.100.0070.0338.68
4.3.90.0030.0308.68
4.3.80.0070.0338.68
4.3.70.0030.0208.68
4.3.60.0030.0338.68
4.3.50.0000.0378.68
4.3.40.0000.0578.68
4.3.30.0070.0308.68
4.3.20.0030.0338.68
4.3.10.0000.0208.68
4.3.00.0030.0238.68

preferences:
142.62 ms | 1394 KiB | 7 Q