You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README-1.6.7.adoc 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. = AspectJ 1.6.7
  2. _© Copyright 2009 Contributors. All rights reserved._
  3. AspectJ 1.6.7 includes some radical internal changes. These improvements
  4. enable faster compilation, faster binary weaving, faster load time
  5. weaving and in some situations faster generated code.
  6. == Pointcut timers
  7. Until 1.6.7 there has not really been a way to determine if it is just
  8. one of your pointcuts that is hurting your weaving performance. In 1.6.7
  9. it is possible to turn on timers for pointcuts. These timers show the
  10. time spent in the weaver matching the pointcut components against join
  11. points. The details on this feature are here:
  12. http://andrewclement.blogspot.com/2009/11/aspectj-profiling-pointcut-matching.html[Profiling
  13. pointcut matching]. Basically by turning on the options '-timers
  14. -verbose' on the command line (or via Ant), output will be produced that
  15. looks a little like this:
  16. [source, text]
  17. ....
  18. Pointcut matching cost (total=6532ms for 675000 joinpoint match calls):
  19. Time:482ms (jps:#168585) matching against
  20. (staticinitialization(*y*.()) && persingleton(SimpleAspect))
  21. Time:3970ms (jps:#168585) matching against
  22. (execution(* *t*.*(*)) && persingleton(SimpleAspect))
  23. Time:538ms (jps:#168584) matching against
  24. (execution(* *f*(..)) && persingleton(SimpleAspect))
  25. Time:1536ms (jps:#168584) matching against
  26. (execution(* java.lang.CharSequence+.*e*(..)) && persingleton(SimpleAspect))
  27. Time:4ms (jps:#662) matching against
  28. (within(*p*) && persingleton(SimpleAspect))
  29. ....
  30. It shows the component, the number of joinpoints (jps) the weaver
  31. attempted to match it against and how many milliseconds were spent
  32. performing those matches. The options can also be turned on
  33. http://contraptionsforprogramming.blogspot.com/2009/11/getting-aspectj-pointcut-matching-timer.html[]through
  34. AJDT. Armed with this information you can optimize your pointcuts or
  35. post on the mailing list asking for help. The timers can even be turned
  36. on for load time weaving.
  37. == Faster matching
  38. The changes to enable pointcut profiling enabled some targeted work to
  39. be done on the matching algorithms. These have remained unchanged for a
  40. few years, but in 1.6.7 have received a bit of an overhaul. 'Fast match'
  41. has been implemented for the execution() pointcut, drastically reducing
  42. weave times for heavy users of execution - more details
  43. http://andrewclement.blogspot.com/2009/11/aspectj-how-much-faster-is-aspectj-167.html[here].
  44. The pointcut cost calculator (which is used to sort pointcuts to
  45. optimize matching speed) has been reviewed and after determining that
  46. this() ought to be considered cheaper than call() - any user combining
  47. those two pointcut designators should see an improvement (one users
  48. build time reduced from 38minutes to 6minutes with that change!).
  49. As well as faster matching there is also less exploration to determine a
  50. match. Visitors that walk hierarchies and discover methods now terminate
  51. as early as possible once they can determine something is a match or is
  52. definetly not a match. This reduces memory usage, speeds up weaving and
  53. reduces the occurrences of those annoying 'cantFindType' messages.
  54. == aop.xml processing
  55. The processing of include/exclude entries in aop.xml has been rewritten.
  56. It now optimizes for many more common patterns. If a pattern is
  57. optimized then there is no need to ask the weaver to do an expensive
  58. include/exclude match. More details
  59. http://andrewclement.blogspot.com/2009/12/aspectj-167-and-faster-load-time.html[here].
  60. == Less need to tweak options for load time weaving
  61. A number of options were previously configurable for load time weaving
  62. that were considered experimental. These options have now been tested
  63. enough in the field that they are considered fully reliable and are on
  64. by default in 1.6.7. If you have been using either of these:
  65. * typeDemotion
  66. * runMinimalMemory
  67. then please delete them from your weaver options section, the weaver
  68. will now do the right thing out of the box.
  69. == Benchmarking memory and performance
  70. All those changes above, and some additional tweaks, mean we are now
  71. using less memory than ever before and getting things done more quickly.
  72. http://andrewclement.blogspot.com/2009/12/aspectj-167-and-faster-load-time.html[This
  73. post] discusses the details. From that article, the graph below shows
  74. the speed and memory consumption of the various AspectJ 1.6 releases
  75. when load time weaving a small application loading in Tomcat. For each
  76. of 10 iterations (x axis), the top comparison is startup time in
  77. milliseconds, the lower comparison is memory used in bytes.
  78. image:images/167speed.png[image]
  79. image:images/167Memory.png[image]
  80. == Annotation binding
  81. All those changes affect compilation/weaving but what about the code
  82. that actually runs? One user, Oliver Hoff, raised a query on the
  83. performance of annotation binding. His case uncovered an old TODO left
  84. in the code a few years ago:
  85. [source, text]
  86. ....
  87. // OPTIMIZE cache result of getDeclaredMethod and getAnnotation?
  88. ....
  89. Annotation binding has become a very common use case since that was
  90. written and 1.6.7 was the time TODO it.
  91. The result is an optimization for the general case of binding an
  92. annotation, but also support for a new bit of syntax that aids binding
  93. of a string annotation member value - using this latter syntax generates
  94. extremely fast code.
  95. Here are some numbers for a simple benchmark retrieving the annotation
  96. value at an execution join point in different ways. The three scenarios
  97. look like this (where the annotation type is 'Marker' and it has a
  98. String value field called 'message'):
  99. [source, java]
  100. ....
  101. // CaseOne: annotation value fetching is done in the advice:
  102. pointcut adviceRetrievesAnnotation(): execution(@Marker * runOne(..));
  103. before(): adviceRetrievesAnnotation() {
  104. Marker marker = (Marker) ((MethodSignature)
  105. thisJoinPointStaticPart.getSignature()).getMethod().getAnnotation(Marker.class);
  106. String s = marker.message();
  107. }
  108. // CaseTwo: annotation binding is done in the pointcut, advice retrieves message
  109. pointcut pointcutBindsAnnotation(Marker l): execution(@Marker * runTwo(..)) && @annotation(l);
  110. before(Marker l): pointcutBindsAnnotation(l) {
  111. String s = l.message();
  112. }
  113. // CaseThree: annotation binding directly targets the message value in the annotation
  114. pointcut pointcutBindsAnnotationValue(String msg):
  115. execution(@Marker * runThree(..)) && @annotation(Marker(msg));
  116. before(String s): pointcutBindsAnnotationValue(s) {
  117. // already got the string
  118. }
  119. ....
  120. Before 1.6.7, case 2 was slower than case 1 and case 3 wasn't supported
  121. syntax. The two bugs with more info are
  122. https://bugs.eclipse.org/bugs/show_bug.cgi?id=296484[Bug 296484] and
  123. https://bugs.eclipse.org/bugs/show_bug.cgi?id=296501[Bug 296501].
  124. Now this is a micro benchmark, slightly unrepresentative of the real
  125. world because the advice isn't doing anything else, but it does really
  126. stress the AspectJ binding code. For the benchmark numbers the join
  127. points advised by those advice were invoked 1,000,000 times. AspectJ
  128. 1.6.7:
  129. [source, text]
  130. ....
  131. Manually fetching annotation with getAnnotation(): 645ms
  132. Binding annotation with @annotation(Marker): 445ms (was >20 *seconds* for 1.6.6, due to an extra reflection call)
  133. Binding annotation value with @annotation(Marker(message)): 3ms
  134. ....
  135. The new syntax is definetly the best way to bind an annotation string
  136. value.
  137. '''''
  138. [[bugsfixed]]
  139. === Bugs fixed
  140. The complete list of issues resolved for AspectJ 1.6.7 can be found with
  141. this bugzilla query:
  142. * https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced&short_desc_type=allwordssubstr&short_desc=&product=AspectJ&target_milestone=1.6.7&long_desc_type=allwordssubstr&long_desc=&bug_file_loc_type=allwordssubstr&bug_file_loc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=allwords&keywords=&bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&emailtype1=substring&email1=&emailtype2=substring&email2=&bugidtype=include&bug_id=&votes=&chfieldfrom=&chfieldto=Now&chfieldvalue=&cmdtype=doit&order=Reuse+same+sort+as+last+time&field0-0-0=noop&type0-0-0=noop&value0-0-0=[Bugs
  143. resolved]
  144. '''''