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 regression on startup (in particular in AnnotationUtils) [SPR-13621] #18199

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

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 29, 2015

Stéphane Nicoll opened SPR-13621 and commented

There is a major performance regression on annotations lookup in Spring Framework 4.2. We found out that a basic Spring Boot application was 10% slower between 1.2 and 1.3. We did some investigation and found out that a Spring boot 1.3 app based on 4.2 was also 10% slower than the same app on 4.1

One of the major hotspot difference is AnnotationUtils.findAnnotation. On 4.1 its own time is 23 ms (232ms in total) while on 4.2 it is 1,936ms (5,340ms in total)


Affects: 4.2.2

Issue Links:

1 votes, 10 watchers

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Based on my attempts today, a particularly wasteful part seems to be the synthesize step for annotations on re-retrieval: While we have been caching the original annotation result, we always re-synthesize the entire annotation for every lookup call... I've modified this to cache the synthesized result now which should provide a significant boost for re-retrieval attempts. However, I have no idea how much of a difference this makes in actual Boot startup time, so please re-run the tests there, Stéphane Nicoll...

If this doesn't provide enough benefit yet, we could also try to skip the synthesize step altogether for lookup attempts where it doesn't make an actual difference, i.e. where the calling code is ok with aliased attributes to be exposed independently (which it may signal through a boolean flag). However, let's see where the change above takes us first.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

A few further steps taken in the meantime:

We're avoiding our rather expensive annotation retrieval algorithm in common callers of AnnotatedElementUtils when there are no annotations to begin with: e.g. in StandardAnnotationMetadata, AutowiredAnnotationBeanPostProcessor, AnnotationTransactionAttributeSource. StandardAnnotationMetadata also caches the annotation array now, avoiding repeated re-retrieval.

AnnotatedElementUtils consistently operates on the actual annotation type if available, avoiding String name comparisons in favor of annotation type identity checks wherever possible. Also, it avoids double getDeclaredAnnotations/getAnnotations checks on anything other than Classes now - since they'll always deliver the same result for Methods etc anyway, just in a wasteful fresh array.

I've also fixed our new 4.2 order determination check in ConfigurationClassUtils so that it only kicks in for actual configuration candidates; it was running through an unnecessary Order annotation lookup for every single bean in the context before.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

As a further step, we're avoiding annotation synthesizing for getAnnotationAttributes retrieval now, in particular affecting ASM-based introspection during component scans.

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

No branches or pull requests

2 participants