diff options
Diffstat (limited to 'docs/dist/doc/README-167.html')
-rw-r--r-- | docs/dist/doc/README-167.html | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/docs/dist/doc/README-167.html b/docs/dist/doc/README-167.html new file mode 100644 index 000000000..11c0737d1 --- /dev/null +++ b/docs/dist/doc/README-167.html @@ -0,0 +1,165 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> <head> +<title>AspectJ 1.6.7 Readme</title> +<style type="text/css"> +<!-- + P { margin-left: 20px; } + PRE { margin-left: 20px; } + LI { margin-left: 20px; } + H4 { margin-left: 20px; } + H3 { margin-left: 10px; } +--> +</style> +</head> + +<body> +<div align="right"><small> +© Copyright 2009 Contributors. +All rights reserved. +</small></div> + +<h1>AspectJ 1.6.7 Readme</h1> + +<p>AspectJ 1.6.7 includes some radical internal changes. These improvements enable faster compilation, faster binary weaving, +faster load time weaving and in some situations faster generated code.</p> + +<h2>Pointcut timers</h2> +<p>Until 1.6.7 there has not really been a way to determine if it is just one of your pointcuts that is hurting your weaving +performance. In 1.6.7 it is possible to turn on timers for pointcuts. These timers show +the time spent in the weaver matching the pointcut components against join points. The details on this feature are +here: <a href="http://andrewclement.blogspot.com/2009/11/aspectj-profiling-pointcut-matching.html">Profiling pointcut +matching</a>. Basically by turning on the options '-timers -verbose' on the command line (or via Ant), output will be produced +that looks a little like this: + +<pre><code> +Pointcut matching cost (total=6532ms for 675000 joinpoint match calls): +Time:482ms (jps:#168585) matching against + (staticinitialization(*y*.()) && persingleton(SimpleAspect)) +Time:3970ms (jps:#168585) matching against + (execution(* *t*.*(*)) && persingleton(SimpleAspect)) +Time:538ms (jps:#168584) matching against + (execution(* *f*(..)) && persingleton(SimpleAspect)) +Time:1536ms (jps:#168584) matching against + (execution(* java.lang.CharSequence+.*e*(..)) && persingleton(SimpleAspect)) +Time:4ms (jps:#662) matching against + (within(*p*) && persingleton(SimpleAspect)) +</code></pre> + +<p>It shows the component, the number of joinpoints (jps) the weaver attempted to match it against and how many milliseconds were +spent performing those matches. The options can also be turned on +<a href="http://contraptionsforprogramming.blogspot.com/2009/11/getting-aspectj-pointcut-matching-timer.html"/>through AJDT</a>. +Armed with this information you can optimize your pointcuts or post on the mailing list asking for help. The timers can even be +turned on for load time weaving. </p> + + +<h2>Faster matching</h2> + +<p>The changes to enable pointcut profiling enabled some targeted work to be done on the matching algorithms. These +have remained unchanged for a few years, but in 1.6.7 have received a bit of an overhaul. 'Fast match' has +been implemented for the execution() pointcut, drastically reducing weave times for heavy users of execution - more details +<a href="http://andrewclement.blogspot.com/2009/11/aspectj-how-much-faster-is-aspectj-167.html">here</a>. The pointcut cost +calculator (which is used to sort pointcuts to optimize matching speed) has been reviewed and after determining that +this() ought to be considered cheaper than call() - any user combining those two pointcut designators should see an improvement +(one users build time reduced from 38minutes to 6minutes with that change!).</p> + +<p>As well as faster matching there is also less exploration to determine a match. Visitors that walk hierarchies and discover +methods now terminate as early as possible once they can determine something is a match or is definetly not a match. This reduces +memory usage, speeds up weaving and reduces the occurrences of those annoying 'cantFindType' messages.</p> + +<h2>aop.xml processing</h2> + +<p>The processing of include/exclude entries in aop.xml has been rewritten. It now optimizes for many more common patterns. If +a pattern is optimized then there is no need to ask the weaver to do an expensive include/exclude match. More details +<a href="http://andrewclement.blogspot.com/2009/12/aspectj-167-and-faster-load-time.html">here</a>. + +<h2>Less need to tweak options for load time weaving</h2> + +<p>A number of options were previously configurable for load time weaving that were considered experimental. These options +have now been tested enough in the field that they are considered fully reliable and are on by default in 1.6.7. If you have +been using either of these: +<ul> +<li>typeDemotion +<li>runMinimalMemory +</ul> +<p>then please delete them from your weaver options section, the weaver will now do the right thing out of the box.</p> + +<h2>Benchmarking memory and performance</h2> + +<p>All those changes above, and some additional tweaks, mean we are now using less memory than ever before and getting +things done more quickly.</p> +<p><a href="http://andrewclement.blogspot.com/2009/12/aspectj-167-and-faster-load-time.html">This post</a> discusses +the details. From that article, the graph below shows the speed and memory consumption of the +various AspectJ 1.6 releases when load time weaving a small application loading in Tomcat. For each of 10 iterations (x axis), +the top comparison is startup time in +milliseconds, the lower comparison is memory used in bytes.</p> +<p><img src="167Memory.png" align="center"/></p> + +<h2>Annotation binding</h2> + +<p>All those changes affect compilation/weaving but what about the code that actually runs? One user, Oliver Hoff, raised +a query on the performance of annotation binding. His case uncovered an old TODO left in the code a few years ago:</p> +<code><pre>// OPTIMIZE cache result of getDeclaredMethod and getAnnotation?</pre></code> + +<p>Annotation binding has become a very common use case since that was written and 1.6.7 was the time TODO it.</p> + +<p>The result is an optimization for the general case of binding an annotation, but also support for a new bit of syntax +that aids binding of a string annotation member value - using this latter syntax generates extremely fast code.</p> + +<p>Here are some numbers for a simple benchmark retrieving the annotation value at an execution join point +in different ways. The three scenarios look like this (where the annotation type is 'Marker' and it has a String value field +called 'message'):</p> + +<code><pre> + // CaseOne: annotation value fetching is done in the advice: + pointcut adviceRetrievesAnnotation(): execution(@Marker * runOne(..)); + before(): adviceRetrievesAnnotation() { + Marker marker = (Marker) ((MethodSignature) + thisJoinPointStaticPart.getSignature()).getMethod().getAnnotation(Marker.class); + String s = marker.message(); + } + + // CaseTwo: annotation binding is done in the pointcut, advice retrieves message + pointcut pointcutBindsAnnotation(Marker l): execution(@Marker * runTwo(..)) && @annotation(l); + before(Marker l): pointcutBindsAnnotation(l) { + String s = l.message(); + } + + // CaseThree: annotation binding directly targets the message value in the annotation + pointcut pointcutBindsAnnotationValue(String msg): + execution(@Marker * runThree(..)) && @annotation(Marker(msg)); + before(String s): pointcutBindsAnnotationValue(s) { + // already got the string + } +</pre></code> + +<p>Before 1.6.7, case 2 was slower than case 1 and case 3 wasn't supported syntax. The two bugs with more info are +<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296484">Bug 296484</a> and +<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296501">Bug 296501</a>.</p> + +<p>Now this is a micro benchmark, slightly unrepresentative of the real world because the advice isn't doing anything +else, but it does really stress the AspectJ binding code. For the benchmark numbers the join points advised by those advice +were invoked 1,000,000 times. AspectJ 1.6.7:</p> + +<code><pre> +Manually fetching annotation with getAnnotation(): 645ms +Binding annotation with @annotation(Marker): 445ms (was >20 *seconds* for 1.6.6, due to an extra reflection call) +Binding annotation value with @annotation(Marker(message)): 3ms +</pre></code> + +<p>The new syntax is definetly the best way to bind an annotation string value.</p> + +<hr> + +<a name="bugsfixed"/> +<h4>Bugs fixed</h4> +<p>The complete list of issues resolved for AspectJ 1.6.7 can be found with +this bugzilla query: +<ul> +<li><a href="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 resolved</a> +</ul> +<hr> + +<h4> +<!-- ============================== --> +</body> +</html> |