Jump to: navigation, search

AspectJBuildSpeed

This page describes possible enhancements to speed up the build cycle. Tips here are not to speed up your program, but to reduce the time it takes to compile your program.

AspectJ weaving process is computationally intensive. The AspectJ developers are very careful about weaver performances, but as a user there are a number of techniques that can improve your build speed.

Measure your current speed

TODO

Generic speed tips

Use incremental compilations

AspectJ is able to re-weave classes. This way, it's possible for the weaver to reweave only modified classes.

To achieve incremental compilations, you should not delete classes netween two build cycles. If you are using a tool like ANT or MAVEN to build your AspectJ project, avoid calling "clean" targets if not really needed. (2)

Use abstract aspects instead of generic ones

If you need to write a generic aspect, that matches many places in your code and then performs some kind of checks (like some "if") to decide what to do, then you probably should write an abstract aspect and then subclass it when needed.

This way the weaver will not apply the generic one to many places, but instead apply only the concrete subclasses. (2)

Update to a version higher than 1.6.4

A lot of work has been done on speeding up build and reducing ram requirements in versions 1.6.3 and 1.6.4. If you are still using version before 1.6.4, it would be a really good idea to update.

Give more RAM

If your project gets big and you have many aspects, it could be the case that you require more RAM than the default JVM will take by default. If you are building inside Eclipse, modify your eclipse.ini file to add the "-Xmx" option, if you are using ANT or MAVEN then use the ANT_OPTS and MAVEN_OPTS environment variables to set the same JVM option.

Speeding up class matching

Class matching tries to determine if the current class matches any of the type patterns used in your aspects.

To speed up matching, AspectJ tries a number of different checks, trying to use faster checks first.

Use aop.xml scoping

The first check performed is for aspect scoping. You can define the scope for your aspect when using include and exclude elements in xml configuration, as explained in ltw configuration instructions.

Note: while working on enhancement 124460 , Andrew Clement implemented support for aop.xml files also at compile time, as explained in his announcement email.

Use execution() instead of call()

Execution is better than call. execution will just advise one place (where the 'thing' is defined) whilst call will advise every location calling the 'thing'. (1)

Use within() wherever possible, expecially with execution()

execution() is by definition generic. In fact, execution(public void MyType.doSomething()) includes also execution of doSomething() in every subclass of MyType. So, for each class the weaver encounters, it tries to determine if it extends MyType. If you intend to only match execution of setSomething in MyType, you should add within(MyType).

This will narrow the type matching and speed up weaving of execution().

Consider the impact of runtime checks, like cflow(), if() etc..

The weaver is not able to check for all pointcuts at compile time. Pointcuts like cflow() and if() are evaluable only at runtime. So, when you use them, the weaver will weave every point in the code that matches the rest of the pointcut expression, and perform the last check at runtime.

For example, an expression like execution(void *.get*()) && cflow(execution(Database.*())) will weave each getter found, and perform the check for the cflow only at runtime.

Fine tune your inpath

The more libraries you have on your inpath, the more types AspectJ will need to check for each aspect. The inpath should contain only libraries that really needs to be weaved, otherwise your build time can easily get far longer than really needed.

Things you don't need to do

As opposed to Java evaluation of expressions, AspectJ will reorder your pointcut definitions so that it can speed them up. So, there is no reason to write them in a specific order. (1)

Load time weaving and compile time weaving have nearly identical performances. Whether you obtain a faster developement cycle using LTW or CTW largely depends on your program. LTW will weave only loaded classes, which could speed things up, but on the opposite it is not able to do incremental builds, so it needs to reweave everything everytime.


References

(1) : Andrew Clement "RE: QUESTION: Optimizing pointcuts for performance" on aspectj-users mailing list.

(2) : Andrew Eisenberg "RE: compile time performance (Eclipse 3.3)" on aspectj-users mailing list.