Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8029019

(ann) Optimize annotation handling in core reflection

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P3 P3
    • tbd
    • 8, 9
    • core-libs

      Peter writes:

      Hi,

      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:

      http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/webrev.01/


      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
      StringBuffer

      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()
      and cloneArray()

      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
      micro-benchmarks:

      http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/test/perf_results.txt

      These results are obtained with the following test:

      http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/test/AnnotationDispatchPerfTest.java
      http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/test/si/pele/microbench/TestRunner.java


      In short:
      - 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?

      Regards, Peter

            plevart Peter Levart
            jfranck Joel Borggrén-Franck (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: