|
AnnotationUtils is primarily used by i18n mechanism in order to identify translatable getters and types. Used in conjunction with ProxyToys interceptors AnnotationUtils conducts the look up whether a method has the annotation applied to it. This means that *every i18n-ed definition method call* results into:
- class hierarchy look-up (we need to get all the parent types and all method implementations and check whether any of them has annotation applied).
- multiple class/method annotation look-up
- since Reflections library is used to look-up/filter the annotations, some collections and other garbage objects are created on the way (we are still talking about a getter call!)
Load tests have shown that these reflective operations due to their high amount tend to consume a lot of CPU.
Easiest way to mitigate the issue is to cache the results of the look-ups:
- cache class hierarchies
- cache the method/type annotations
Experiments have proved that this renders the resource consumption by AnnotationUtils to minimum.
Potential follow-up:
- it still seems that rather frequent I18N-ization calls in UI are causing *some* resource waste (nothing compared to above but still). This is related to CGLIB bytecode transformations being involved in the process (heavy!). The suggestion here is to consider i18n-ed API for the definition provider. I.e. besides of DefinitionProvider#get() we could also have DefinitionProvider#getLocalised() which will produce an i18n-ised proxy once (until the underlying config changes of course).
|