Description
Symfony version(s) affected: 4.4.11
Description
Injecting services with complicated service graphs causes large compilation slowdown compared to simply injecting container.
This comes as a surprise, since injecting services directly comes as universal recommendation, people are instructed to do it in migration guides from Symfony 3.x to 4.x and is even recommended for performance reasons, while I observe opposite.
How to reproduce
- Download project.zip
composer install
time bin/console
Notice the time. In my case this is around 10s without xdebug and 1m:5s with xdebug.
Now do
Index: project/src/AppBundle/Controller/Admin/Settings/FormFieldTypeController.php
===================================================================
@@ -12,9 +12,9 @@
class FormFieldTypeController extends AbstractController
{
public function __construct(
- PanelHandlerAll $panelHandlerAll,
- CustomPanelLoader $customPanelLoader
-// ContainerInterface $container
+ ContainerInterface $container
) {
}
}
Run time bin/console
again. Notice the time. In my case this is around 3s without xdebug and around 15s with xdebug.
Now, why did I mention this is O(n) vs O(1) problem:
In Resources/config/services/_default.yml
file is c1
..c26
service defined. In case of injecting service container, it doesn't really matter how many of them there are, compilation speed is pretty much constant. However in other case, speed is very much dependant on number of these service definitions.
Additional context
I originally raised this issue on Slack. @nicolas-grekas encouraged me to create this issue ;) I was working on converting the retrieval of our public services to injecting them directly, as officially recommended as Symfony best practice. In middle of this I discovered compilation times got much worse than originally, as opposed to just injecting the ContainerInterface as was done before. I have spent lot of time gutting our application so I can provide reproducer, I hope it's useful, even though I know it's not perfect.
Possibly related: #37540. However, marking the services private has no impact on performance in my case.
Blackfire link: https://blackfire.io/profiles/17769187-521c-48d3-8600-3de9adece809/graph (this is from before I gutted the application into reproducer)