Jonas Bonér bio photo

Jonas Bonér

Present.
Entrepreneur.
Hacker.
Public Speaker.
Powder Skier.
Perpetual Learner.
Jazz Fanatic.
Wannabee Musician.

Twitter LinkedIn Github

There has been a lot of talk about the JBoss AOP implementation (and its lack of performance) lately.

When looking at it you can see (as Rickard and many others already have pointed out) that it has soo many major flaws that it is impossible for it to perform anything but bad.

Apart from this, one of the things that first hit me was that the implementation is completely lacking a decent join point model (meaning some sort of "language" in which you can define which methods/fields etc. should be advised). They are simply advising *everything* and are then (at runtime) making the desicions if an advice should be invoked or not. This is really amazing, since the key to a good AOP framework lies in how expressive and rich the join point model is. Those that have used AOP for some time will agree on that it is not enough to pick out join points on class level only:

 <!-- from the JBoss tutorial -->
 <interceptor-pointcut class="com.acme.POJO.*">
       <interceptors>
         <interceptor factory="jboss.security.SecurityFactory"/>
         <interceptor-ref name="Logging"/>
       </interceptors>
   </interceptor-pointcut>
but there is a need for a much more finegrained selection mechanism, or you will run into a scaling wall pretty quick.

In my world I would like to (at least) be able to pick out join points based on:

  • class pattern
  • method pattern, including return type and parameter types
  • field pattern, including field type
  • a mechanism to combine these patterns in an expression (e.g. ((pc1 || pc2) && pc3) and similar)
(Of course AspectWerkz supports all of these.)

I could not resist to implement and run the same performance tests that Rickard did for JBoss AOP. Here are the results using AspectWerkz (running on my Pentium 4 2.54 Mhz box):

  • overhead for non-advised method: 0.0 ms/call (since non-advised calls are not advised)
  • overhead for advised method but no advice (advice removed): 0.0003 ms/call
  • invoking a method with one advice that does nothing: 0.0005 ms/call
  • invoking a method with a chain of ten advices that does nothing: 0.0024 ms/call
  • overhead for a call to an introduced method: 0.0004 ms/call