Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[DI] Improve performance of removing/inlining passes #27471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2018

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Jun 1, 2018

Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? no
Deprecations? yes
Tests pass? yes
Fixed tickets #27386
License MIT
Doc PR -

Here is an optimization to reclaim some compilation time by optimizing the analysis of unused and inlined services.

This PR removes any use case for RepeatedPass, instead:

  • RemoveUnusedDefinitionsPass works in one run, removing all private services that are unreachable from public services
  • InlineServiceDefinitionsPass reduces the number of nodes to analyze per iteration using AnalyzeServiceReferencesPass on a duplicated container internally.

https://blackfire.io/profiles/compare/00723822-6c09-431c-b98d-4a4197d044fc/graph?settings%5Bdimension%5D=wt&settings%5Bdisplay%5D=focused&settings%5BtabPane%5D=nodes&selected=Symfony%5CComponent%5CDependencyInjection%5CCompiler%5CRepeatedPass%3A%3Aprocess&callname=Symfony%5CComponent%5CDependencyInjection%5CCompiler%5CRepeatedPass%3A%3Aprocess

image

@nicolas-grekas
Copy link
Member Author

@tarlepp since you reported a slowdown on Slack, can you please try this PR and report any results?

@staabm
Copy link
Contributor

staabm commented Jun 3, 2018

The blackfire link in the desc doesnt work

@nicolas-grekas
Copy link
Member Author

@staabm updated thanks.

Note that our test suite is pretty nice on this topic, coverage is pretty great. I also used this patch to compile Blackfire's container, and it produces exactly same output. Confidence is good on my side :)

@nicolas-grekas nicolas-grekas changed the base branch from master to 4.1 June 3, 2018 08:35
@nicolas-grekas nicolas-grekas force-pushed the di-perf branch 2 times, most recently from 0bf53a9 to ae832d5 Compare June 3, 2018 21:19
@nicolas-grekas nicolas-grekas changed the base branch from 4.1 to master June 3, 2018 21:27
@nicolas-grekas nicolas-grekas modified the milestones: 4.1, next Jun 3, 2018
@nicolas-grekas nicolas-grekas force-pushed the di-perf branch 2 times, most recently from 21effb3 to 75114e9 Compare June 4, 2018 06:41
Copy link
Member

@chalasr chalasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UPGRADE notes are missing

@@ -16,6 +16,8 @@
* RepeatedPass.
*
* @author Johannes M. Schmitt <[email protected]>
*
* @deprecated since Symfony 4.1.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4.2 :)

@@ -11,13 +11,17 @@

namespace Symfony\Component\DependencyInjection\Compiler;

@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.1.', RepeatedPass::class), E_USER_DEPRECATED);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

@nicolas-grekas
Copy link
Member Author

Do we need upgrade notes here? This is mostly internal thing IMHO.

$srcIdsCount = 0;
foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
$srcId = $edge->getSourceNode()->getId();
$this->connectedIds[$srcId] = true;
if ($edge->isWeak()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if an edge is weak, other edges will not be marked as connected here. Is is expected ?

}

if (count(array_unique($ids)) > 1) {
if (1 !== \count($srcIds)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the difference between \count($srcIds) and $srcIdsCount ? If $srcIdsCount is the number of references (and so a single service referencing it multiple times is counted multiple times), the variable name is not clear.

@@ -101,6 +112,19 @@ protected function processValue($value, $isRoot = false)
ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()
);

if ($this->inExpression) {
$this->inExpression = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why making it false again ? Wouldn't this break in case an expression is referencing multiple services ?

@@ -32,6 +32,7 @@ class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass
*/
public function process(ContainerBuilder $container)
{
$this->enableExpressionProcessing();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about that ? Replacing a reference inside the expression won't change the expression anyway. It will keep using the alias.

@@ -27,6 +27,7 @@ class ResolveReferencesToAliasesPass extends AbstractRecursivePass
*/
public function process(ContainerBuilder $container)
{
$this->enableExpressionProcessing();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about that ? Replacing a reference inside the expression won't change the expression anyway. It will keep using the alias.

@nicolas-grekas
Copy link
Member Author

@stof agreed, thanks for the review, comments addressed.

@Tobion
Copy link
Contributor

Tobion commented Jun 5, 2018

Thank you @nicolas-grekas.

@Tobion Tobion merged commit cf375e5 into symfony:master Jun 5, 2018
Tobion added a commit that referenced this pull request Jun 5, 2018
…nicolas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[DI] Improve performance of removing/inlining passes

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | #27386
| License       | MIT
| Doc PR        | -

Here is an optimization to reclaim some compilation time by optimizing the analysis of unused and inlined services.

This PR removes any use case for `RepeatedPass`, instead:
- `RemoveUnusedDefinitionsPass` works in one run, removing all private services that are unreachable from public services
-  `InlineServiceDefinitionsPass` reduces the number of nodes to analyze per iteration using `AnalyzeServiceReferencesPass` on a duplicated container internally.

https://blackfire.io/profiles/compare/00723822-6c09-431c-b98d-4a4197d044fc/graph?settings%5Bdimension%5D=wt&settings%5Bdisplay%5D=focused&settings%5BtabPane%5D=nodes&selected=Symfony%5CComponent%5CDependencyInjection%5CCompiler%5CRepeatedPass%3A%3Aprocess&callname=Symfony%5CComponent%5CDependencyInjection%5CCompiler%5CRepeatedPass%3A%3Aprocess

![image](https://user-images.githubusercontent.com/243674/40884496-c31e780e-6714-11e8-8218-967c4b25b9ce.png)

Commits
-------

cf375e5 [DI] Improve performance of removing/inlining passes
@nicolas-grekas nicolas-grekas deleted the di-perf branch June 5, 2018 19:35
@nicolas-grekas nicolas-grekas modified the milestones: next, 4.2 Nov 1, 2018
This was referenced Nov 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants