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

Skip to content

Injecting certain services causes O(n) compilation complexity, while injecting Container is O(1) #37850

Closed
@ostrolucky

Description

@ostrolucky

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

  1. Download project.zip
  2. composer install
  3. 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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions