Skip to content

Commit 37d0137

Browse files
[DI] fix minor perf regression when creating non-shared services
1 parent c86f6c2 commit 37d0137

9 files changed

+73
-19
lines changed

Dumper/PhpDumper.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -864,13 +864,23 @@ protected function {$methodName}($lazyInitialization)
864864
}
865865

866866
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
867-
$factoryCode = $asFile ? "\$this->load('%s', false)" : '$this->%s(false)';
868-
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName));
867+
$factoryCode = $definition->isShared() ? ($asFile ? "\$this->load('%s', false)" : '$this->%s(false)') : '$this->factories[%2$s](false)';
868+
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->doExport($id)));
869869
$code .= $asFile ? preg_replace('/function \(([^)]*+)\) {/', 'function (\1) use ($container) {', $factoryCode) : $factoryCode;
870870
}
871871

872872
$code .= $this->addServiceInclude($id, $definition);
873-
$code .= $this->addInlineService($id, $definition);
873+
$c = $this->addInlineService($id, $definition);
874+
875+
if (!$definition->isShared()) {
876+
$c = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $c)));
877+
$factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
878+
$lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : '';
879+
880+
$c = sprintf(" %s = function (%s) {\n%s };\n\n return %1\$s();\n", $factory, $lazyloadInitialization, $c);
881+
}
882+
883+
$code .= $c;
874884
}
875885

876886
if ($asFile) {
@@ -1880,10 +1890,14 @@ private function getServiceCall(string $id, Reference $reference = null): string
18801890
$code = sprintf('$this->%s[%s] = %s', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code);
18811891
}
18821892
$code = "($code)";
1883-
} elseif ($this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition)) {
1884-
$code = sprintf("\$this->load('%s')", $this->generateMethodName($id));
18851893
} else {
1886-
$code = sprintf('$this->%s()', $this->generateMethodName($id));
1894+
$code = $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) ? "\$this->load('%s')" : '$this->%s()';
1895+
$code = sprintf($code, $this->generateMethodName($id));
1896+
1897+
if (!$definition->isShared()) {
1898+
$factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
1899+
$code = sprintf('(isset(%s) ? %1$s() : %s)', $factory, $code);
1900+
}
18871901
}
18881902
if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
18891903
$code = sprintf('($this->%s[%s] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code);

Tests/Fixtures/php/services9_as_files.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,11 @@ class getFooBarService extends ProjectServiceContainer
402402
*/
403403
public static function do($container, $lazyLoad = true)
404404
{
405-
return new \Bar\FooClass(($container->services['deprecated_service'] ?? $container->load('getDeprecatedServiceService')));
405+
$container->factories['foo_bar'] = function () use ($container) {
406+
return new \Bar\FooClass(($container->services['deprecated_service'] ?? $container->load('getDeprecatedServiceService')));
407+
};
408+
409+
return $container->factories['foo_bar']();
406410
}
407411
}
408412

@@ -574,7 +578,11 @@ class getNonSharedFooService extends ProjectServiceContainer
574578
{
575579
include_once $container->targetDir.''.'/Fixtures/includes/foo.php';
576580

577-
return new \Bar\FooClass();
581+
$container->factories['non_shared_foo'] = function () use ($container) {
582+
return new \Bar\FooClass();
583+
};
584+
585+
return $container->factories['non_shared_foo']();
578586
}
579587
}
580588

Tests/Fixtures/php/services9_compiled.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,11 @@ protected function getFoo_BazService()
275275
*/
276276
protected function getFooBarService()
277277
{
278-
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->getDeprecatedServiceService()));
278+
$this->factories['foo_bar'] = function () {
279+
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->getDeprecatedServiceService()));
280+
};
281+
282+
return $this->factories['foo_bar']();
279283
}
280284

281285
/**

Tests/Fixtures/php/services9_inlined_factories.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,11 @@ class ProjectServiceContainer extends Container
300300
*/
301301
protected function getFooBarService()
302302
{
303-
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->getDeprecatedServiceService()));
303+
$this->factories['foo_bar'] = function () {
304+
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->getDeprecatedServiceService()));
305+
};
306+
307+
return $this->factories['foo_bar']();
304308
}
305309

306310
/**
@@ -398,7 +402,11 @@ class ProjectServiceContainer extends Container
398402
{
399403
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
400404

401-
return new \Bar\FooClass();
405+
$this->factories['non_shared_foo'] = function () {
406+
return new \Bar\FooClass();
407+
};
408+
409+
return $this->factories['non_shared_foo']();
402410
}
403411

404412
/**

Tests/Fixtures/php/services_almost_circular_public.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,15 @@ protected function getFoo2Service()
287287
*/
288288
protected function getFoo4Service()
289289
{
290-
$instance = new \stdClass();
290+
$this->factories['foo4'] = function () {
291+
$instance = new \stdClass();
291292

292-
$instance->foobar = ($this->services['foobar4'] ?? $this->getFoobar4Service());
293+
$instance->foobar = ($this->services['foobar4'] ?? $this->getFoobar4Service());
293294

294-
return $instance;
295+
return $instance;
296+
};
297+
298+
return $this->factories['foo4']();
295299
}
296300

297301
/**

Tests/Fixtures/php/services_errored_definition.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,11 @@ protected function getFoo_BazService()
275275
*/
276276
protected function getFooBarService()
277277
{
278-
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->getDeprecatedServiceService()));
278+
$this->factories['foo_bar'] = function () {
279+
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->getDeprecatedServiceService()));
280+
};
281+
282+
return $this->factories['foo_bar']();
279283
}
280284

281285
/**

Tests/Fixtures/php/services_non_shared_lazy.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ protected function createProxy($class, \Closure $factory)
5757
*/
5858
protected function getBarService()
5959
{
60-
return $this->services['bar'] = new \stdClass($this->getFooService());
60+
return $this->services['bar'] = new \stdClass((isset($this->factories['service_container']['foo']) ? $this->factories['service_container']['foo']() : $this->getFooService()));
6161
}
6262

6363
/**
@@ -69,7 +69,11 @@ protected function getFooService($lazyLoad = true)
6969
{
7070
// lazy factory for stdClass
7171

72-
return new \stdClass();
72+
$this->factories['service_container']['foo'] = function ($lazyLoad = true) {
73+
return new \stdClass();
74+
};
75+
76+
return $this->factories['service_container']['foo']();
7377
}
7478
}
7579

Tests/Fixtures/php/services_non_shared_lazy_as_files.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ class getNonSharedFooService extends ProjectServiceContainer
3030
{
3131
include_once $container->targetDir.''.'/Fixtures/includes/foo_lazy.php';
3232

33-
return new \Bar\FooLazyClass();
33+
$container->factories['non_shared_foo'] = function ($lazyLoad = true) {
34+
return new \Bar\FooLazyClass();
35+
};
36+
37+
return $container->factories['non_shared_foo']();
3438
}
3539
}
3640

Tests/Fixtures/php/services_service_locator_argument.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ protected function getFoo2Service()
107107
*/
108108
protected function getFoo3Service()
109109
{
110-
return new \stdClass();
110+
$this->factories['service_container']['foo3'] = function () {
111+
return new \stdClass();
112+
};
113+
114+
return $this->factories['service_container']['foo3']();
111115
}
112116

113117
/**

0 commit comments

Comments
 (0)