Skip to content

Improve performance of AbstractAutowireCapableBeanFactory#predictBeanType #24681

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

Conversation

dreis2211
Copy link
Contributor

@dreis2211 dreis2211 commented Mar 11, 2020

Hi,

I am currently trying to improve startup time of a medium sized Spring-Boot app that currently takes around 20 seconds to start. While profiling I noticed that the top hotspot is AbstractAutowireCapableBeanFactory#predictBeanType as shown in the screenshot below:

image

Additionally you can seeIterator.hasNext()/next() which are also in the top of the list. I found out that a reasonable time is spent iterating over BeanPostProcessors (23 in my case) for every bean, although most of the post-processors are not a SmartInstantiationAwareBeanPostProcessor at all (only 3 in my case), which are the only post-processors of interest for predicting bean types. Even worse, almost all standard smart post-processors are anyway returning null.

The idea of this PR is to hold an additional list of smart post-processors that can be used to minimize the iteration overhead in cases where only SmartInstantiationAwareBeanPostProcessor instances are of interest. Applying this patch shows the following results in the profiling and saves around 1-2 seconds for me:

image

Let me know what you think.
Cheers,
Christoph

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Mar 11, 2020
@dreis2211
Copy link
Contributor Author

dreis2211 commented Mar 21, 2020

If #24756 is merged, this PR needs to adapt as well. Or vice versa, obviously.

@dreis2211
Copy link
Contributor Author

Anyone willing to review?

@sbrannen sbrannen requested a review from jhoeller April 8, 2020 10:39
@sbrannen sbrannen added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Apr 8, 2020
@jhoeller
Copy link
Contributor

jhoeller commented Apr 8, 2020

I suppose you are trying to optimize singleton creation performance there, that is, many separate beans of distinct types? I was wondering before whether to cache post-processor applicability to individual beans but that would only improve repeated creation attempts for non-singleton beans...

@dreis2211
Copy link
Contributor Author

dreis2211 commented Apr 8, 2020

It's indeed many separate @Services or @Components we're talking about, each of them autowiring a couple of other beans (let's say 5 on average - but that is only based on a gut-feeling). And before you ask: I unfortunately can't provide the application at hand. :/

@jhoeller jhoeller self-assigned this Apr 8, 2020
@dreis2211
Copy link
Contributor Author

dreis2211 commented Apr 28, 2020

Any chance this might be included in the next release, @jhoeller ? (5.3.0 or even better: 5.2.7)

@jhoeller jhoeller removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 28, 2020
@jhoeller jhoeller added this to the 5.3 M1 milestone Apr 28, 2020
@dreis2211
Copy link
Contributor Author

I think that could also help on #22060

@jhoeller
Copy link
Contributor

I've implemented a different approach: an internal cache for pre-filtered post-processors, used within the AbstractBeanFactory hierarchy with no impact on outside packages. This is as fine-grained as possible now, differentiating not only SmartInstantiationAware but regular InstantiationAware, DestructionAware and MergedBeanDefinitionPostProcessor as well, also replacing the existing hasInstantiationAware and hasDestructionAware fields with the new single volatile post-processor cache... which is getting reset in addBeanPostProcessor.

To be committed ASAP, I'll simply repurpose this PR for it (I hope you're ok with that approach).

@dreis2211
Copy link
Contributor Author

dreis2211 commented May 13, 2020

Obviously, I appreciate a contribution as much as anyone - but I care more about the problem being fixed, so feel free to go on. I'll take a look once you committed it, because I can't really tell from your description if that actually solves the problem (of simply too many iterations on irrelevant post processors)

@jhoeller jhoeller closed this in a3c5625 May 13, 2020
kenny5he pushed a commit to kenny5he/spring-framework that referenced this pull request Jun 21, 2020
Also includes bulk addition in PostProcessorRegistrationDelegate.

Closes spring-projectsgh-24681
Closes spring-projectsgh-24756
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) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants