Skip to content
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

Performance degradation with singleton pattern and container.getAll() for explicit dependency injection #1578

Open
unadlib opened this issue Aug 29, 2024 · 1 comment

Comments

@unadlib
Copy link
Contributor

unadlib commented Aug 29, 2024

Expected Behavior

When using InversifyJS with the singleton pattern and explicit dependency injection:

  1. The performance should remain consistent regardless of the order of dependencies in the list.
  2. Using container.getAll() to retrieve dependency instances should not cause significant performance degradation, even with complex dependency graphs.

Current Behavior

  1. When modules with more dependencies are placed earlier in the list for explicit injection, it leads to significant performance degradation.
  2. The performance worsens as the number of dependencies and the complexity of the dependency graph increases.
  3. Using container.getAll() to iterate through the list and obtain each dependency instance becomes increasingly slow with larger and more complex dependency lists.

Possible Solution

  1. Optimize the way InversifyJS resolves and instantiates dependencies in the singleton pattern, especially when using container.getAll().
  2. Implement a caching mechanism for resolved dependencies to reduce repeated resolution of complex dependency chains.
  3. Provide an alternative method to container.getAll() that is more efficient for large dependency graphs.
  4. Offer guidance on optimal ordering of dependencies to minimize performance impact.

Steps to Reproduce (for bugs)

  1. Set up a project using InversifyJS with the singleton pattern.
  2. Create a list of dependencies for explicit injection, with modules having varying numbers of dependencies. Ensure some modules have complex dependency chains.
  3. Use container.getAll() to retrieve instances of these dependencies.
  4. Measure performance with different orderings of the dependency list, particularly with more complex dependencies at the beginning vs. the end of the list.
  5. Observe the performance difference and increased resolution time as the list grows and more complex dependencies are moved to the front.

Additional context:

  • This issue becomes more pronounced in larger applications with numerous dependencies.
  • The performance impact may vary depending on the specific structure of the dependency graph.
@notaphplover
Copy link
Member

Hey @unadlib,

Inversify's architecture has their pros and cons. It allows to provide a vast variety of features other libraries simply can't. But as you correctly guessed it comes with a cost: the planner relies on complex graphs which are constantly being recreatead. Therefore, inversify needs to create the plan and traverse it to instantiate the object. Generating plans comes with an intensive use of GC, allocating and freeing a vast amount of objects, that's not performant friendly at all.

But singleton instances are cached, you should enjoy the benefits of caching this way.

So, are you saying container.getAll is not relying on cached singleton instances? Just to know, let's try to figure out a way to recreate this with a relatively simple case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

2 participants