Skip to content

[DependencyInjection] Improve performance of the generated code. #9432

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

Closed
wants to merge 2 commits into from

Conversation

realityking
Copy link
Contributor

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

I noticed a couple of ways the code generated for the compiler could be improved:

  1. As mentioned in Support for private services as configurator #3758 configurators can not be private (it's just ignored). The first commit in this pull changes that and allows them to be inlined. It it also creates better code if a configurator is used multiple times for one service (i.e. to both inject it and configure the same service) but this should be very rare.

Note that this patch generates different code on 5.4 to prevent a call to call_user_func. If that's not desired I'll revert that part.

  1. When using static methods for either the factory or as the configurator we can avoid using call_user_func and directly use the class:method notation. This is done by the second commit.

TODO:

  • add a unit test covering an inlined configurator

@staabm
Copy link
Contributor

staabm commented Nov 23, 2013

@fabpot @realityking what do you think of adding https://github.com/polyfractal/athletic performance tests to verify this speedup thing and make sure it won't regress?

if ($callable[0] instanceof Definition) {
if ($this->definitionVariables->contains($callable[0])) {
return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
} elseif (version_compare(PHP_VERSION, '5.4.0') >= 0) {
Copy link
Member

Choose a reason for hiding this comment

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

if is enough as the previous if returns

@stof
Copy link
Member

stof commented Nov 23, 2013

This PR is actually doing 2 unrelated things:

  • fixing a bug about private configurators being ignored.
  • improving performances of the dumped code (for which I'm not sure it works properly for complex cases).

These 2 things should be done in separate PRs, which can be reviewed and merged separately. The bug fix is probably far quicker to review and merge than the performance improvements (especially given that I find them suspicious in my first quick review). Thus, the bugfix should probably be merged in 2.2 while the improvements can only go in master.
Can you provide 2 separate PRs ?

@raziel057
Copy link
Contributor

@staabm +1 for integration of such tool like https://github.com/polyfractal/athletic

@realityking
Copy link
Contributor Author

Took me a bit to get back to this. I'd be happy to split them, but I'm a bit unsure whether the configurator patch should be done to 2.3. The fix is a bit more involved and there's no bug in the sense that something breaks - it's just a missed optimization opportunity. Thoughts?

@fabpot
Copy link
Member

fabpot commented Dec 9, 2013

Optimizations must be done on master only (except if the patch is simple enough to understand and it the performance gain is very significant).

@ghost
Copy link

ghost commented Dec 16, 2013

ubot detected some small issues in this pull request.

You can make the modifications by hand or run the following command from the repository root directory:

curl http://ubot.io/patch/symfony/symfony/9432.diff | patch -p0
diff -ru src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
--- src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php  2013-12-16 16:30:17.631122873 +0000
+++ src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php  2013-12-16 16:30:18.803122873 +0000
@@ -710,6 +710,7 @@
                 if (strpos($class, "'") === 0) {
                     return sprintf("        $return{$instantiation}%s::%s(%s);\n", substr($class, 1, -1), $definition->getFactoryMethod(), $arguments ? implode(', ', $arguments) : '');
                 }
+
                 return sprintf("        $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $class, $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
             }

@realityking
Copy link
Contributor Author

I'll spin the second commit off after the first is merged since it depends on the first.

fabpot added a commit that referenced this pull request Dec 16, 2013
…urators (realityking)

This PR was merged into the 2.5-dev branch.

Discussion
----------

[DependencyInjection] added support for inlining Configurators

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

This is one commit from #9432.

As mentioned in #3758 configurators can not be private (it's just ignored). This pull changes that and allows them to be inlined. It it also creates better code if a configurator is used multiple times for one service (i.e. to both inject it and configure the same service, or to configure multiple inlined services) but this should be very rare.

Commits
-------

4e9aa07 [DependencyInjection] added support for inlining Configurators
@fabpot
Copy link
Member

fabpot commented Dec 16, 2013

#9791 has been merged now

@realityking
Copy link
Contributor Author

I'm closing this one as I've opened a pull request with the other code. I excluded the different path that only works on PHP 5.4 as that would be difficult to test for very little gain, maybe something to consider for 3.0.

@stof I'd appreciate it if you'd look over the new pull request as well.

@realityking realityking deleted the dic_performance branch December 17, 2013 21:26
fabpot added a commit that referenced this pull request Dec 18, 2013
…ainers. (realityking)

This PR was merged into the 2.5-dev branch.

Discussion
----------

[DependencyInjection] Avoid call_user_func in dumped containers.

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

This is the second commit from  #9432.

When using static methods for either the factory or as the configurator we can avoid using call_user_func and directly use the class:method notation. This is faster (about 5 times, but we're talking milliseconds here) but I think the resulting code is also much easier to read.

The code to use call_user_func has to remain in PhpDumper because in the uncompiled container they still get used.

Commits
-------

be1eaaa [DependencyInjection] Avoid call_user_func in dumped containers.
nicolas-grekas added a commit that referenced this pull request May 19, 2016
… more cases (realityking)

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

Discussion
----------

[DependencyInjection] Avoid generating call_user_func in more cases

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

This is a follow up to #9807 to add the PHP 5.4 only coded I excluded when I split it off #9432.

Commits
-------

2718a6c [DependencyInjection] Avoid generating call_user_func in more cases
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.

5 participants