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

Improve performance of #getBeanNamesForType() while the BeanFactory configuration is not yet frozen [SPR-13610] #18188

Closed
spring-projects-issues opened this issue Oct 26, 2015 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: duplicate A duplicate of another issue type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 26, 2015

Steffen Ryll opened SPR-13610 and commented

We have a pretty large ApplicationContext with about 7600 Beans and startup times have become an issue, now at 5.5 min just for the ApplicationContext. We observed that all the steps in AbstractApplicationContext#refresh before #preInstantiateSingletons() is called take about 90 seconds (excluding the time it takes to load all bean definition XML files). About 81 seconds of that time seems to be spent in the method DefaultListableBeanFactory#getBeanNamesForType.

In order to better understand where time is spent, we've build a wrapper around DefaultListableBeanFactory that measures the execution time of calls to #createBean, #getBeanNamesForType and #applyBeanPostProcessors*Initialization/Instantiation. This is the tooling we used to get the numbers mentioned above.

Closer inspection shows that runtime performance of #getBeanNamesForType depends heavily on the flag #isConfigurationFrozen - as long as it is set to false during AppCtx refresh, each call takes about 10 seconds, when it is set to true, calls typically take only ~100 ms.

A particular issue seems to me, that #getBeanNamesForType is called at least three times for the type BeanDefinitionRegistryPostProcessor, so that's more than 30 seconds in our scenario. I found that this has been implemented as part of #15258, and comments in the code of PostProcessorRegistrationDelegate indicate that calling it three times is "by design". But that seems like a waste of time to me, given that these calls take rather long.

Please let's discuss which optimizations would be feasible here within the boundaries of the involved interface contracts.


Affects: 4.0.7, 4.2.1

Issue Links:

4 votes, 10 watchers

@spring-projects-issues
Copy link
Collaborator Author

Steffen Ryll commented

Here are the details, which calls to getBeanNamesForType during refresh() take how long:

  • getBeanNamesForType() (frozen=false) for Type BeanDefinitionRegistryPostProcessor took: 14452 ms
  • getBeanNamesForType() (frozen=false) for Type BeanDefinitionRegistryPostProcessor took: 7452 ms
  • getBeanNamesForType() (frozen=false) for Type BeanDefinitionRegistryPostProcessor took: 11886 ms
  • getBeanNamesForType() (frozen=false) for Type BeanFactoryPostProcessor dauerte took: 13819 ms
  • getBeanNamesForType() (frozen=false) for Type BeanPostProcessor took: 7335 ms
  • getBeanNamesForType() (frozen=false) for Type Advisor took: 9153 ms
  • getBeanNamesForType() (frozen=false) for Type ApplicationListener took: 7328 took
  • getBeanNamesForType() (frozen=false) for Type LoadTimeWeaverAware took: 10496 ms

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Fair enough, with that size of context, those calls may take painfully long. We'll revisit this for 4.3, trying to optimize based on the metadata that we have at each given point... but also exploring options for explicit hints in the application's configuration, allowing us to bypass entire steps (e.g. if we know that there is nothing to find for this particular application anyway). We may even go as far as using pre-computed indexes for certain steps, which has been suggested in other cases before; not sure whether that part can happen for 4.3 though.

Juergen

@jhoeller
Copy link
Contributor

This should have significantly improved in 5.2 already, based on #23336 and #23337. So this is effectively a duplicate at this point.

@jhoeller jhoeller added the status: duplicate A duplicate of another issue label Feb 26, 2024
@jhoeller jhoeller removed this from the 6.2.0-M1 milestone Feb 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants