merged branch tgabi333/master (PR #8891)

This PR was submitted for the master branch but it was merged into the 2.2 branch instead (closes #8891).

Discussion
----------

[DependencyInjection] optimized circular reference checker

| Q             | A
| ------------- | ---
| Bug fix?      | [no]
| New feature?  | [no]
| BC breaks?    | [no]
| Deprecations? | no]
| Tests pass?   | [yes]
| Fixed tickets | []
| License       | MIT
| Doc PR        | []

It is an addtion to my previous PR https://github.com/symfony/symfony/pull/7699

There is no need to check again previously checked sub-trees.

In our tightly coupled services graph, this circular reference check runs avg 1,5ms, before that: 100ms

Commits
-------

67ebf8f optimized circular reference checker
This commit is contained in:
Fabien Potencier 2013-08-30 13:28:31 +02:00
commit 480dda41cf

View File

@ -28,6 +28,7 @@ class CheckCircularReferencesPass implements CompilerPassInterface
{ {
private $currentId; private $currentId;
private $currentPath; private $currentPath;
private $checkedNodes;
/** /**
* Checks the ContainerBuilder object for circular references. * Checks the ContainerBuilder object for circular references.
@ -38,6 +39,7 @@ class CheckCircularReferencesPass implements CompilerPassInterface
{ {
$graph = $container->getCompiler()->getServiceReferenceGraph(); $graph = $container->getCompiler()->getServiceReferenceGraph();
$this->checkedNodes = array();
foreach ($graph->getNodes() as $id => $node) { foreach ($graph->getNodes() as $id => $node) {
$this->currentId = $id; $this->currentId = $id;
$this->currentPath = array($id); $this->currentPath = array($id);
@ -58,6 +60,8 @@ class CheckCircularReferencesPass implements CompilerPassInterface
foreach ($edges as $edge) { foreach ($edges as $edge) {
$node = $edge->getDestNode(); $node = $edge->getDestNode();
$id = $node->getId(); $id = $node->getId();
if (empty($this->checkedNodes[$id])) {
$searchKey = array_search($id, $this->currentPath); $searchKey = array_search($id, $this->currentPath);
$this->currentPath[] = $id; $this->currentPath[] = $id;
@ -66,7 +70,10 @@ class CheckCircularReferencesPass implements CompilerPassInterface
} }
$this->checkOutEdges($node->getOutEdges()); $this->checkOutEdges($node->getOutEdges());
$this->checkedNodes[$id] = true;
array_pop($this->currentPath); array_pop($this->currentPath);
} }
} }
} }
}