<?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";
- Output for 7.4.1
- dice1: 0.098487854003906
dice1: 0.13987302780151
- Output for 7.4.0
- dice1: 0.15138792991638
dice1: 0.17864298820496
- Output for 7.3.13
- dice1: 0.11382603645325
dice1: 0.12907004356384
- Output for 7.3.12
- dice1: 0.15213298797607
dice1: 0.17740392684937
- Output for 7.3.11
- dice1: 0.15152597427368
dice1: 0.17994999885559
- Output for 7.3.10
- dice1: 0.091226816177368
dice1: 0.15614104270935
- Output for 7.3.9
- dice1: 0.093512058258057
dice1: 0.13041520118713
- Output for 7.3.8
- dice1: 0.09822416305542
dice1: 0.11356115341187
- Output for 7.3.7
- dice1: 0.1145920753479
dice1: 0.10931205749512
- Output for 7.3.6
- dice1: 0.11103105545044
dice1: 0.12623596191406
- Output for 7.3.5
- dice1: 0.091375112533569
dice1: 0.10761380195618
- Output for 7.3.4
- dice1: 0.10699391365051
dice1: 0.132248878479
- Output for 7.3.3
- dice1: 0.11683893203735
dice1: 0.10931515693665
- Output for 7.3.2
- dice1: 0.097058773040771
dice1: 0.11345314979553
- Output for 7.3.1
- dice1: 0.10513186454773
dice1: 0.11128401756287
- Output for 7.3.0
- dice1: 0.097787141799927
dice1: 0.17400002479553
- Output for 7.2.26
- dice1: 0.12713503837585
dice1: 0.1342499256134
- Output for 7.2.25
- dice1: 0.18664193153381
dice1: 0.18514013290405
- Output for 7.2.24
- dice1: 0.15007781982422
dice1: 0.13468408584595
- Output for 7.2.23
- dice1: 0.13126015663147
dice1: 0.16795492172241
- Output for 7.2.22
- dice1: 0.1794228553772
dice1: 0.20521378517151
- Output for 7.2.21
- dice1: 0.13047289848328
dice1: 0.15037894248962
- Output for 7.2.20
- dice1: 0.11342811584473
dice1: 0.13013219833374
- Output for 7.2.19
- dice1: 0.12611794471741
dice1: 0.14485096931458
- Output for 7.2.18
- dice1: 0.11282587051392
dice1: 0.17422795295715
- Output for 7.2.17
- dice1: 0.12418699264526
dice1: 0.13054919242859
- Output for 7.2.16
- dice1: 0.17545199394226
dice1: 0.20595502853394
- Output for 7.2.15
- dice1: 0.14497208595276
dice1: 0.15172719955444
- Output for 7.2.14
- dice1: 0.13191604614258
dice1: 0.1278350353241
- Output for 7.2.13
- dice1: 0.14213895797729
dice1: 0.20148801803589
- Output for 7.2.12
- dice1: 0.15009999275208
dice1: 0.20444393157959
- Output for 7.2.11
- dice1: 0.17492985725403
dice1: 0.12817311286926
- Output for 7.2.10
- dice1: 0.11300086975098
dice1: 0.12781000137329
- Output for 7.2.9
- dice1: 0.1764509677887
dice1: 0.1506769657135
- Output for 7.2.8
- dice1: 0.16740012168884
dice1: 0.12847495079041
- Output for 7.2.7
- dice1: 0.16094493865967
dice1: 0.2038049697876
- Output for 7.2.6
- dice1: 0.1740939617157
dice1: 0.15483522415161
- Output for 7.2.5
- dice1: 0.11376595497131
dice1: 0.13774704933167
- Output for 7.2.4
- dice1: 0.12278509140015
dice1: 0.15810799598694
- Output for 7.2.3
- dice1: 0.17562317848206
dice1: 0.20487904548645
- Output for 7.2.2
- dice1: 0.11256289482117
dice1: 0.13894414901733
- Output for 7.2.1
- dice1: 0.17254018783569
dice1: 0.17473006248474
- Output for 7.2.0
- dice1: 0.11739301681519
dice1: 0.1281111240387
- Output for 7.1.33
- dice1: 0.16297101974487
dice1: 0.20281910896301
- Output for 7.1.32
- dice1: 0.22570204734802
dice1: 0.22528791427612
- Output for 7.1.31
- dice1: 0.16521692276001
dice1: 0.18235301971436
- Output for 7.1.30
- dice1: 0.21394801139832
dice1: 0.21149301528931
- Output for 7.1.29
- dice1: 0.15164494514465
dice1: 0.19760799407959
- Output for 7.1.28
- dice1: 0.21991896629333
dice1: 0.25322198867798
- Output for 7.1.27
- dice1: 0.16892099380493
dice1: 0.19208002090454
- Output for 7.1.26
- dice1: 0.17674088478088
dice1: 0.18678593635559
- Output for 7.1.25
- dice1: 0.2209050655365
dice1: 0.22902202606201
- Output for 7.1.24
- dice1: 0.18927311897278
dice1: 0.18939208984375
- Output for 7.1.23
- dice1: 0.18588614463806
dice1: 0.17119288444519
- Output for 7.1.22
- dice1: 0.16437411308289
dice1: 0.1899311542511
- Output for 7.1.21
- dice1: 0.14704418182373
dice1: 0.1802179813385
- Output for 7.1.20
- dice1: 0.18621206283569
dice1: 0.18798089027405
- Output for 7.1.19
- dice1: 0.22329092025757
dice1: 0.21168279647827
- Output for 7.1.18
- dice1: 0.21025800704956
dice1: 0.202388048172
- Output for 7.1.17
- dice1: 0.17316818237305
dice1: 0.16695380210876
- Output for 7.1.16
- dice1: 0.16573596000671
dice1: 0.18766283988953
- Output for 7.1.15
- dice1: 0.14779114723206
dice1: 0.1667308807373
- Output for 7.1.14
- dice1: 0.16358208656311
dice1: 0.20326018333435
- Output for 7.1.13
- dice1: 0.19689798355103
dice1: 0.26251888275146
- Output for 7.1.12
- dice1: 0.21196484565735
dice1: 0.16630697250366
- Output for 7.1.11
- dice1: 0.17734885215759
dice1: 0.24361896514893
- Output for 7.1.10
- dice1: 0.19281196594238
dice1: 0.25317096710205
- Output for 7.1.9
- dice1: 0.17797017097473
dice1: 0.19722414016724
- Output for 7.1.8
- dice1: 0.22784900665283
dice1: 0.19921398162842
- Output for 7.1.7
- dice1: 0.2182788848877
dice1: 0.24824595451355
- Output for 7.1.6
- dice1: 0.1782910823822
dice1: 0.25451493263245
- Output for 7.1.5
- dice1: 0.1697199344635
dice1: 0.19603204727173
- Output for 7.1.4
- dice1: 0.16944789886475
dice1: 0.25401496887207
- Output for 7.1.3
- dice1: 0.20213508605957
dice1: 0.17531085014343
- Output for 7.1.2
- dice1: 0.14584302902222
dice1: 0.22098398208618
- Output for 7.1.1
- dice1: 0.19878911972046
dice1: 0.26252388954163
- Output for 7.1.0
- dice1: 0.16470313072205
dice1: 0.19106197357178
- Output for 7.0.33
- dice1: 0.1669590473175
dice1: 0.20406699180603
- Output for 7.0.32
- dice1: 0.16143894195557
dice1: 0.24043011665344
- Output for 7.0.31
- dice1: 0.17905783653259
dice1: 0.21863317489624
- Output for 7.0.30
- dice1: 0.17407512664795
dice1: 0.2121160030365
- Output for 7.0.29
- dice1: 0.21732401847839
dice1: 0.24104595184326
- Output for 7.0.28
- dice1: 0.25198793411255
dice1: 0.20294904708862
- Output for 7.0.27
- dice1: 0.18872308731079
dice1: 0.22497701644897
- Output for 7.0.26
- dice1: 0.23223209381104
dice1: 0.21724987030029
- Output for 7.0.25
- dice1: 0.18308186531067
dice1: 0.19200491905212
- Output for 7.0.24
- dice1: 0.25629687309265
dice1: 0.25819516181946
- Output for 7.0.23
- dice1: 0.20296692848206
dice1: 0.21627998352051
- Output for 7.0.22
- dice1: 0.2423210144043
dice1: 0.29699397087097
- Output for 7.0.21
- dice1: 0.17935800552368
dice1: 0.19967103004456
- Output for 7.0.20
- dice1: 0.24908995628357
dice1: 0.22483515739441
- Output for 7.0.19
- dice1: 0.17351198196411
dice1: 0.25399208068848
- Output for 7.0.18
- dice1: 0.16363096237183
dice1: 0.18916010856628
- Output for 7.0.17
- dice1: 0.25338506698608
dice1: 0.24702882766724
- Output for 7.0.16
- dice1: 0.18567609786987
dice1: 0.22126698493958
- Output for 7.0.15
- dice1: 0.22270202636719
dice1: 0.21089601516724
- Output for 7.0.14
- dice1: 0.25175404548645
dice1: 0.23890900611877
- Output for 7.0.13
- dice1: 0.25243401527405
dice1: 0.23451900482178
- Output for 7.0.12
- dice1: 0.19222402572632
dice1: 0.22430992126465
- Output for 7.0.11
- dice1: 0.17708992958069
dice1: 0.20299506187439
- Output for 7.0.10
- dice1: 0.22588181495667
dice1: 0.29941606521606
- Output for 7.0.9
- dice1: 0.18240094184875
dice1: 0.21848106384277
- Output for 7.0.8
- dice1: 0.23680901527405
dice1: 0.29135799407959
- Output for 7.0.7
- dice1: 0.25037407875061
dice1: 0.20935201644897
- Output for 7.0.6
- dice1: 0.20121192932129
dice1: 0.21193504333496
- Output for 7.0.5
- dice1: 0.249675989151
dice1: 0.30051302909851
- Output for 7.0.4
- dice1: 0.18359708786011
dice1: 0.21011209487915
- Output for 7.0.3
- dice1: 0.22176718711853
dice1: 0.19516205787659
- Output for 7.0.2
- dice1: 0.16812205314636
dice1: 0.20349097251892
- Output for 7.0.1
- dice1: 0.25118398666382
dice1: 0.20812296867371
- Output for 7.0.0
- dice1: 0.22596120834351
dice1: 0.18937301635742
- Output for 5.6.40
- dice1: 0.32786202430725
dice1: 0.37826704978943
- Output for 5.6.39
- dice1: 0.39960885047913
dice1: 0.51919794082642
- Output for 5.6.38
- dice1: 0.31560111045837
dice1: 0.47677397727966
- Output for 5.6.37
- dice1: 0.36726498603821
dice1: 0.46855497360229
- Output for 5.6.36
- dice1: 0.35541200637817
dice1: 0.48911595344543
- Output for 5.6.35
- dice1: 0.33558297157288
dice1: 0.5508828163147
- Output for 5.6.34
- dice1: 0.40856885910034
dice1: 0.43115401268005
- Output for 5.6.33
- dice1: 0.42089700698853
dice1: 0.54299306869507
- Output for 5.6.32
- dice1: 0.38715577125549
dice1: 0.44865083694458
- Output for 5.6.31
- dice1: 0.3379819393158
dice1: 0.40429615974426
- Output for 5.6.30
- dice1: 0.31940197944641
dice1: 0.38083100318909
- Output for 5.6.29
- dice1: 0.31409811973572
dice1: 0.56529307365417
- Output for 5.6.28
- dice1: 0.40390086174011
dice1: 0.43451404571533
- Output for 5.6.27
- dice1: 0.31348180770874
dice1: 0.38778495788574
- Output for 5.6.26
- dice1: 0.41605496406555
dice1: 0.52028107643127
- Output for 5.6.25
- dice1: 0.48804306983948
dice1: 0.4844069480896
- Output for 5.6.24
- dice1: 0.31269383430481
dice1: 0.38869190216064
- Output for 5.6.23
- dice1: 0.31069993972778
dice1: 0.45700883865356
- Output for 5.6.22
- dice1: 0.40988802909851
dice1: 0.46039915084839
- Output for 5.6.21
- dice1: 0.31339597702026
dice1: 0.37965297698975
- Output for 5.6.20
- dice1: 0.49491286277771
dice1: 0.43242192268372
- Output for 5.6.19
- dice1: 0.36661815643311
dice1: 0.39101195335388
- Output for 5.6.18
- dice1: 0.42260694503784
dice1: 0.4585428237915
- Output for 5.6.17
- dice1: 0.46696901321411
dice1: 0.47130393981934
- Output for 5.6.16
- dice1: 0.34119510650635
dice1: 0.39710998535156
- Output for 5.6.15
- dice1: 0.37250113487244
dice1: 0.38285613059998
- Output for 5.6.14
- dice1: 0.4230170249939
dice1: 0.62871408462524
- Output for 5.6.13
- dice1: 0.339271068573
dice1: 0.5475709438324
- Output for 5.6.12
- dice1: 0.36918520927429
dice1: 0.45436000823975
- Output for 5.6.11
- dice1: 0.50067710876465
dice1: 0.52846598625183
- Output for 5.6.10
- dice1: 0.3199610710144
dice1: 0.61172318458557
- Output for 5.6.9
- dice1: 0.46619296073914
dice1: 0.54691290855408
- Output for 5.6.8
- dice1: 0.32936882972717
dice1: 0.43125700950623
- Output for 5.6.7
- dice1: 0.51431584358215
dice1: 0.45067691802979
- Output for 5.6.6
- dice1: 0.4163990020752
dice1: 0.44631195068359
- Output for 5.6.5
- dice1: 0.48364996910095
dice1: 0.47469305992126
- Output for 5.6.4
- dice1: 0.34692192077637
dice1: 0.39186382293701
- Output for 5.6.3
- dice1: 0.31700301170349
dice1: 0.40292811393738
- Output for 5.6.2
- dice1: 0.32736206054688
dice1: 0.39995193481445
- Output for 5.6.1
- dice1: 0.3614809513092
dice1: 0.38137412071228
- Output for 5.6.0
- dice1: 0.38981008529663
dice1: 0.38146305084229
- Output for 5.4.0 - 5.4.45, 5.5.0 - 5.5.38
- Parse error: syntax error, unexpected '.' in /in/6TKDp on line 220
Process exited with code 255.
preferences:
158.69 ms | 402 KiB | 242 Q