Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4f4c172

Browse filesBrowse files
committed
feature #27268 [DI] fine tune dumped factories (nicolas-grekas)
This PR was merged into the 4.2-dev branch. Discussion ---------- [DI] fine tune dumped factories | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Here is an optimization we forgot in the dumped container: when a private service is referenced once, there is no need to keep it in the internal registry as it will never be reused. This should help a bit the garbage collection process. Commits ------- 88ecd0d [DI] fine tune dumped factories
2 parents 7a8b706 + 88ecd0d commit 4f4c172
Copy full SHA for 4f4c172

File tree

Expand file treeCollapse file tree

5 files changed

+36
-24
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+36
-24
lines changed

‎src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+26-4Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\DependencyInjection\Variable;
1818
use Symfony\Component\DependencyInjection\Definition;
1919
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
20+
use Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphNode;
2021
use Symfony\Component\DependencyInjection\ContainerBuilder;
2122
use Symfony\Component\DependencyInjection\Container;
2223
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -68,6 +69,7 @@ class PhpDumper extends Dumper
6869
private $inlineRequires;
6970
private $inlinedRequires = array();
7071
private $circularReferences = array();
72+
private $singleUsePrivateIds = array();
7173

7274
/**
7375
* @var ProxyDumper
@@ -141,10 +143,14 @@ public function dump(array $options = array())
141143

142144
(new AnalyzeServiceReferencesPass())->process($this->container);
143145
$this->circularReferences = array();
146+
$this->singleUsePrivateIds = array();
144147
$checkedNodes = array();
145148
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
146149
$currentPath = array($id => $id);
147150
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
151+
if ($this->isSingleUsePrivateNode($node)) {
152+
$this->singleUsePrivateIds[$id] = $id;
153+
}
148154
}
149155
$this->container->getCompiler()->getServiceReferenceGraph()->clear();
150156

@@ -526,7 +532,7 @@ private function addServiceInstance(string $id, Definition $definition, string $
526532
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
527533
$instantiation = '';
528534

529-
if (!$isProxyCandidate && $definition->isShared()) {
535+
if (!$isProxyCandidate && $definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
530536
$instantiation = sprintf('$this->%s[\'%s\'] = %s', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $id, $isSimpleInstance ? '' : '$instance');
531537
} elseif (!$isSimpleInstance) {
532538
$instantiation = '$instance';
@@ -819,7 +825,7 @@ private function generateServiceFiles()
819825
$definitions = $this->container->getDefinitions();
820826
ksort($definitions);
821827
foreach ($definitions as $id => $definition) {
822-
if (!$definition->isSynthetic() && !$this->isHotPath($definition)) {
828+
if (!$definition->isSynthetic() && !$this->isHotPath($definition) && ($definition->isPublic() || !$this->isTrivialInstance($definition))) {
823829
$code = $this->addService($id, $definition, $file);
824830

825831
if (!$definition->isShared()) {
@@ -1662,7 +1668,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
16621668
$code = 'null';
16631669
} elseif ($this->isTrivialInstance($definition)) {
16641670
$code = substr($this->addNewInstance($definition, '', '', $id), 8, -2);
1665-
if ($definition->isShared()) {
1671+
if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
16661672
$code = sprintf('$this->%s[\'%s\'] = %s', $definition->isPublic() ? 'services' : 'privates', $id, $code);
16671673
}
16681674
} elseif ($this->asFiles && !$this->isHotPath($definition)) {
@@ -1674,7 +1680,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
16741680
} else {
16751681
$code = sprintf('$this->%s()', $this->generateMethodName($id));
16761682
}
1677-
if ($definition->isShared()) {
1683+
if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
16781684
$code = sprintf('($this->%s[\'%s\'] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $id, $code);
16791685
}
16801686

@@ -1798,6 +1804,22 @@ private function isHotPath(Definition $definition)
17981804
return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated();
17991805
}
18001806

1807+
private function isSingleUsePrivateNode(ServiceReferenceGraphNode $node): bool
1808+
{
1809+
if ($node->getValue()->isPublic()) {
1810+
return false;
1811+
}
1812+
$ids = array();
1813+
foreach ($node->getInEdges() as $edge) {
1814+
if ($edge->isLazy() || !$edge->getSourceNode()->getValue()->isShared()) {
1815+
return false;
1816+
}
1817+
$ids[$edge->getSourceNode()->getId()] = true;
1818+
}
1819+
1820+
return 1 === \count($ids);
1821+
}
1822+
18011823
private function export($value)
18021824
{
18031825
if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) {

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt
+3-13Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
155155
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
156156
// Returns the public 'factory_service_simple' shared service.
157157

158-
return $this->services['factory_service_simple'] = ($this->privates['factory_simple'] ?? $this->load('getFactorySimpleService.php'))->getInstance();
158+
return $this->services['factory_service_simple'] = $this->load('getFactorySimpleService.php')->getInstance();
159159

160160
[Container%s/getFactorySimpleService.php] => <?php
161161

@@ -167,7 +167,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
167167

168168
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
169169

170-
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
170+
return new \SimpleFactoryClass('foo');
171171

172172
[Container%s/getFooService.php] => <?php
173173

@@ -326,7 +326,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
326326
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
327327
// Returns the public 'runtime_error' shared service.
328328

329-
return $this->services['runtime_error'] = new \stdClass(($this->privates['errored_definition'] ?? $this->load('getErroredDefinitionService.php')));
329+
return $this->services['runtime_error'] = new \stdClass($this->load('getErroredDefinitionService.php'));
330330

331331
[Container%s/getServiceFromStaticMethodService.php] => <?php
332332

@@ -351,16 +351,6 @@ return $this->services['tagged_iterator'] = new \Bar(new RewindableGenerator(fun
351351
yield 1 => ($this->privates['tagged_iterator_foo'] ?? $this->privates['tagged_iterator_foo'] = new \Bar());
352352
}, 2));
353353

354-
[Container%s/getTaggedIteratorFooService.php] => <?php
355-
356-
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
357-
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
358-
359-
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
360-
// Returns the private 'tagged_iterator_foo' shared service.
361-
362-
return $this->privates['tagged_iterator_foo'] = new \Bar();
363-
364354
[Container%s/ProjectServiceContainer.php] => <?php
365355

366356
namespace Container%s;

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ protected function getFactoryServiceService()
243243
*/
244244
protected function getFactoryServiceSimpleService()
245245
{
246-
return $this->services['factory_service_simple'] = ($this->privates['factory_simple'] ?? $this->getFactorySimpleService())->getInstance();
246+
return $this->services['factory_service_simple'] = $this->getFactorySimpleService()->getInstance();
247247
}
248248

249249
/**
@@ -381,7 +381,7 @@ protected function getNewFactoryServiceService()
381381
*/
382382
protected function getRuntimeErrorService()
383383
{
384-
return $this->services['runtime_error'] = new \stdClass(($this->privates['errored_definition'] ?? $this->getErroredDefinitionService()));
384+
return $this->services['runtime_error'] = new \stdClass($this->getErroredDefinitionService());
385385
}
386386

387387
/**
@@ -428,7 +428,7 @@ protected function getFactorySimpleService()
428428
{
429429
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
430430

431-
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
431+
return new \SimpleFactoryClass('foo');
432432
}
433433

434434
public function getParameter($name)

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ protected function getFactoryServiceService()
243243
*/
244244
protected function getFactoryServiceSimpleService()
245245
{
246-
return $this->services['factory_service_simple'] = ($this->privates['factory_simple'] ?? $this->getFactorySimpleService())->getInstance();
246+
return $this->services['factory_service_simple'] = $this->getFactorySimpleService()->getInstance();
247247
}
248248

249249
/**
@@ -381,7 +381,7 @@ protected function getNewFactoryServiceService()
381381
*/
382382
protected function getRuntimeErrorService()
383383
{
384-
return $this->services['runtime_error'] = new \stdClass(($this->privates['errored_definition'] ?? $this->getErroredDefinitionService()));
384+
return $this->services['runtime_error'] = new \stdClass($this->getErroredDefinitionService());
385385
}
386386

387387
/**
@@ -428,7 +428,7 @@ protected function getFactorySimpleService()
428428
{
429429
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
430430

431-
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
431+
return new \SimpleFactoryClass('foo');
432432
}
433433

434434
public function getParameter($name)

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ public function getRemovedIds()
6767
*/
6868
protected function getPublicFooService()
6969
{
70-
return $this->services['public_foo'] = new \stdClass(($this->privates['private_foo'] ?? $this->privates['private_foo'] = new \stdClass()));
70+
return $this->services['public_foo'] = new \stdClass(new \stdClass());
7171
}
7272
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.