Field.getAnnotation is dead slow

Discussion in 'Java' started by charlesfr.rey@gmail.com, Nov 12, 2008.

  1. Guest

    Anybody experienced this ?

    It's not noticeable if you don't call getAnnotation often, but if
    somehow you need to do this hundreds or thousands of times, there's a
    good chance you'll notice it.

    I had to implement my own Annotation cache (data structure: Map<Field,
    Map<Class<?>, Annotation>>() ), but what I don't understand is that it
    should already cache the info, looking into the JDK 5 source, in
    Field.java, we have:

    public <T extends Annotation> T getAnnotation(Class<T>
    annotationClass) {
    ...
    return (T) declaredAnnotations().get(annotationClass);
    }

    private transient Map<Class, Annotation> declaredAnnotations;

    private synchronized Map<Class, Annotation> declaredAnnotations() {
    if (declaredAnnotations == null) {
    declaredAnnotations = ... parse annotations ...
    }
    return declaredAnnotations;
    }

    So, it should cache the annotations, but experience shows that it
    doesn't.

    Now, what's possible is that the JVM 5 that I have was not built from
    the source code above ... ? Or am I missing something in the code ?

    Using my own annotation cache (for Fields), performance is 20-25x
    faster.
     
    , Nov 12, 2008
    #1
    1. Advertising

  2. Mark Space Guest

    wrote:

    > Using my own annotation cache (for Fields), performance is 20-25x
    > faster.


    Every piece of documentation I've read on reflection (in Java) says that
    reflection is slow, and advises not to use reflection if you can
    possibly help it.

    I didn't look at your code carefully but I can just about guarantee that
    Java doesn't store annotations in a hash map. They're stored in the
    ..class files and have to be parsed, each time you look them up.

    Also, consider a ConcurrentHashMap instead of a synchronized method. If
    there's any significant concurrency in your program, the concurrent
    version will likely be faster.
     
    Mark Space, Nov 12, 2008
    #2
    1. Advertising

  3. Guest

    On Nov 12, 5:48 pm, Mark Space <> wrote:
    > I didn't look at your code carefully but I can just about guarantee that
    > Java doesn't store annotations in a hash map.  They're stored in the
    > .class files and have to be parsed, each time you look them up.


    The code that I expose in my original post is taken from the source of
    Java's Field class. My question is precisely about why this code does
    a worse job at caching the annotations than a custom application-side
    code.

    Thanks for the answer anyway.

    NB: JDK 5 source can be obtained through http://java.sun.com/j2se/jrl_download.html
    (JDK 6 source for Field.java is similar than version 5, for the part
    that I care about)
     
    , Nov 12, 2008
    #3
  4. Mark Space Guest

    wrote:
    >
    > The code that I expose in my original post is taken from the source of
    > Java's Field class. My question is precisely about why this code does
    > a worse job at caching the annotations than a custom application-side
    > code.



    Hmm, then I don't know. I'm very surprised to see that there's some kind
    of caching at all on the Java API side. I'd have to trace out the code
    and see what's actually being exectued.

    I'd also be concerned about the Map retaining references to the class
    objects after the class objects were no longer used. Seems like this
    could potentially be a memory leak.
     
    Mark Space, Nov 12, 2008
    #4
  5. Mark Space wrote:
    > wrote:
    >>
    >> The code that I expose in my original post is taken from the source
    >> of Java's Field class. My question is precisely about why this code
    >> does a worse job at caching the annotations than a custom
    >> application-side code.

    >
    >
    > Hmm, then I don't know. I'm very surprised to see that there's some
    > kind of caching at all on the Java API side. I'd have to trace out
    > the code and see what's actually being exectued.
    >
    > I'd also be concerned about the Map retaining references to the
    > class
    > objects after the class objects were no longer used. Seems like
    > this
    > could potentially be a memory leak.


    Class object are kept in memory by the Classloader that loaded them.
    So long as the class that keeps the map is loaded by the same
    Classloader, no new memory leaks are introduced.
     
    Mike Schilling, Nov 12, 2008
    #5
  6. schrieb:
    > Anybody experienced this ?
    >
    >...
    > Now, what's possible is that the JVM 5 that I have was not built from
    > the source code above ... ? Or am I missing something in the code ?
    >
    > Using my own annotation cache (for Fields), performance is 20-25x
    > faster.


    As far as I can see is that the Map you are referring to is not used globally
    but locally for each Field instance. Which in return means ich generated
    instance of Field has its own Map and is not aware of any other Map it could use
    for caching purposes. An my guess is your cache Map actually works globally and
    therefore must be alot faster.

    Stefan
     
    Stefan Rybacki, Nov 13, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    3,047
  2. HK
    Replies:
    3
    Views:
    458
  3. mike
    Replies:
    3
    Views:
    399
    Virgil Green
    Jul 11, 2005
  4. Sound
    Replies:
    2
    Views:
    461
    Randy Webb
    Sep 28, 2006
  5. jr
    Replies:
    3
    Views:
    433
Loading...

Share This Page