Assorted annotation optimizations
peter.levart at gmail.com
Sat Nov 2 21:58:08 UTC 2013
I propose a set of straightforward optimizations of annotations in the
field of minimizing garbage creation and execution performance. Here's a
webrev containing the changes:
Changes grouped by class/method:
AnnotationInvocationHandler.invoke(): Use reference comparison among
interned strings instead of equals() to dispatch the invocation and use
Method.getParameterCount() instead of Method.getParameterTypes() to
avoid creating Class array for each invocation.
AnnotationInvocationHandler.toStringImpl(): Use StringBuilder instead of
AnnotationInvocationHandler.equalsImpl(): Don't call asOneOfUs(o) in a
loop for each member and restructure the code to have basically two
independent implementations: the one based on memberValues map if the
other annotation is "OneOfUs" (the common case) and the one based on
AnnotationType.members() map of member methods. Caching of member
methods privately in each AnnotationInvocationHandler instance is not
needed - use the AnnotationType.members() map instead - this improves
annotation instance footprint too.
AnnotationInvocationHandler.getMemberValue(): new static package-private
method used in AnnotationSupport for fast retrieval of shared value
array in container annotations.
AnnotationSupport.getDirectlyAndIndirectlyPresent(): minimize number of
garbage objects and array copies. This method delegates to
getSharedIndirectlyPresent() which might return a shared array which is
only cloned if needed.
AnnotationSupport.getSharedIndirectlyPresent(): private method instead
of getIndirectlyPresent() that may return a shared array.
AnnotationSupport.getSharedValueArray(): private method that may return
a shared array. This method is based on new
AnnotationInvocationHandler.getMemberValue() method and now also
incorporates a call to checkTypes().
AnnotationSupport.getValueArray(): now based on getSharedValueArray()
AnnotationSupport.cloneArray(): new private method which clones the array
AnnotationSupport.newArray(): new private constructor for annotation
arrays (to localize @SuppressWarnings("unchecked"))
AnnotationType constructor: member Methods are now all made
setAccessible(true) in advance so that "value" member method for
container annotations doesn't need to be made setAccessible(true) each
time a container of a particular type is flattened.
All in all these changes make common operations such as retrieving the
annotation member values and obtaining repeatable annotations faster and
with less produced garbage objects. Here are the results of some
These results are obtained with the following test:
- Invoking Annotation.annotationType() is 6x faster
- Retrieving a scalar member value is 2x faster
- Annotation.equals for annotation with 3 int members is 2.5x faster
- Class.getDeclaredAnnotationsByType for direct-only case is 2x faster
- Class.getDeclaredAnnotationsByType for in-direct-only case is 2.2x faster
- Class.getDeclaredAnnotationsByType for mixed case is 1.7x faster
So what do you think?
More information about the core-libs-dev