Community
Participate
Working Groups
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2009010218 Gentoo Firefox/3.0.5 Build Identifier: 20090619-0625 AspectJ 1.6.6 Thanks to Oliver Hoff for reporting this. When @annotation(x) is used to extract an annotation in a pointcut, AspectJ weaves the following code : 49: ldc #1; //class tests/SampleProgram 51: ldc #92; //String calc 53: iconst_0 54: anewarray #74; //class java/lang/Class 57: invokevirtual #78; //Method java/lang/Class.getDeclaredMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method; 60: ldc #71; //class tests/Log 62: invokevirtual #84; //Method java/lang/reflect/Method.getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation; 65: checkcast #71; //class tests/Log 68: invokevirtual #91; //Method tests/Intercept.ajc$afterReturning$tests_Intercept$2$74fc38c9:(Ltests/Log;)V Which uses getDeclaredMethod to find the current method. If however the @annotation(x) is not used, and the annotation is extracted inside the advice using Log log = (Log) ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().getAnnotation(Log.class); this is 10 times faster than the code produced by AspectJ. This makes using @annotation a performance problem, while it could probably be optimized in two ways : - Use thisJoinPointStaticPart to make it a performance-equivalent - Annotation could even be cached and reused, without calling getAnnotation every time, to make it even more efficient. Reproducible: Always Steps to Reproduce: 1. See attached sample project 2. Comment/uncomment the two advices in Intercept.aj
Created attachment 153350 [details] Sample project, provided by Oliver Hoff, demonstrating the performance problem
Yes, when I looked at the generated code last night I came to the same conclusion as Simone. This stuff hasn't been reviewed since first being added in 1.5.0. Caching the annotation seems the best option for now.
Just found this tag in the AspectJ source :D // OPTIMIZE cache result of getDeclaredMethod and getAnnotation?
:D
Changes are in to cache, it is quicker, but it is not as quick as the syntax for binding the string directly (see bug 296501). Numbers for 1,000,000 iterations: Manually fetching annotation with getAnnotation(): 645ms Binding annotation with @annotation(Marker): 445ms (was > 20seconds) Binding annotation value with @annotation(Marker(message)): 3ms
fixed