Discussions

News: Spring AOP Performance Tuning

  1. Spring AOP Performance Tuning (16 messages)

    Recently, the AspectWerkz team released their AWBench benchmarking suite to performance test a variety of different AOP implementations. The published figures have recently been updated with a new profile for Spring 1.1.3 which shows a noticeable improvement in overall performance.

    AWBench is a great utility for all AOP implementations and certainly I will be using it extensively in my continued work on the Spring AOP proxy architecture.

    The latest figures can found at: http://docs.codehaus.org/display/AW/AOP+Benchmark.

    Everyone interested in tuning their Spring AOP implementations should download the AWBench code and check out the optimized configuration used for the tests.

    Also, I'm interested to know - do you consider raw performance to be important when dealing with AOP and if not, what do value most in a good AOP implementation?

    Threaded Messages (16)

  2. Spring AOP Performance Tuning[ Go to top ]

    Certainly I would like Spring AOP to be as fast is as reasonably possible, but no, I don't think raw performance is Spring AOP's main selling point. Honestly, the main selling point is Spring's declarative transaction management, and if you're hitting a DB that's likely to be orders of magnitude slower than the AOP implementation anyway, so improvements in AOP performance are unlikely to be noticeable. I even use the BeanNameAutoProxyCreator to proxy many more classes with transaction management than should strictly be necessary... that's how unconcerned I am regarding internal performance of the app server :)

    One area where Spring's performance *could* be improved, IMHO, is in the implementation of the TransactionInterceptor. Please see Spring SPR-572 for details.
  3. Spring AOP Performance Tuning[ Go to top ]

    Raw AOP performance is Spring is very important to me. I am glad that the Aspect AOP benchmark adds some public pressure for getting those numbers down.

    The Spring 1.2 release includes classes such as DependencyInjectionAspectSupport which make it easy to add DI to your non-singleton POJOs, such as Hibernate-hydrated classes. Once you have DI everywhere, your design becomes much cleaner, and you don't have to keep playing games of Hunt the ApplicationContext at inopportune places in your code.

    However, current Spring AOP performance is too poor for me to use this in my largest application, so I have to use less elegant approaches to achieve DI.
  4. Re: Spring AOP Performance Tuning[ Go to top ]

    Hi Corby

    I'm currently lead architect on (yet) another Java
    SE + EE framework, called BeanPlanet. This framework
    used AOP and DI through dynamic proxies etc.

    Our basic and rough-and-ready testing sees DI using
    dymanic proxies as 40 or so times slower than the
    equivalent direct method calls.

    I'd be interested in learning why your larger projects
    can't currently use Spring AOP as we could factor your
    feedback into BeanPlanet?

    Thanks in advance,

    Gary Watson + BeanPlanet Team.
    ___________________________________________________
  5. Spring AOP Performance Tuning[ Go to top ]

    Corby,

    Work is under way in Spring to add a great number of options to the AOP framework with regards to proxying. Currently we are looking at three different options for improving AOP performance - I see no reason for us not to be able to rival the performance of other proxy-based AOP frameworks.

    What kind of load testing did you do to identify Spring AOP as the bottleneck for your application? I'd be interested to know, to see if we can use a similar testing profile for our continued work on the proxy implementations.

    Rob
  6. Spring AOP Performance Tuning[ Go to top ]

    Replicating my situation should be pretty straightforward.

    1) Load about 10K - 15K POJOs into a secondary cache such as EHCache.

    2) Define a transaction that enlists each of these POJOs and invokes a business method with low overhead.

    3) Define some trivial advice to occur on each invocation of the business method.

    4) Run through the test with and without the advice applied to determine the overhead incurred by Spring AOP.

    Feel free to contact me at cepage at gmail.com if you have further questions.
  7. Spring AOP Performance Tuning[ Go to top ]

    Replicating my situation should be pretty straightforward.1) Load about 10K - 15K POJOs into a secondary cache such as EHCache.2) Define a transaction that enlists each of these POJOs and invokes a business method with low overhead.3) Define some trivial advice to occur on each invocation of the business method.4) Run through the test with and without the advice applied to determine the overhead incurred by Spring AOP.Feel free to contact me at cepage at gmail.com if you have further questions.

    I found it is not a good idea to intercept "structs", but it is possible to generate special (performant) proxy for "get/set" method interception and "dirty" flag management.
    The most trivial and performant way to implement it is to transform class itself in custom classloader or with custom build tool.
    You can try both ways using cglib (find examples cglib in tests).
  8. Spring AOP Performance Tuning[ Go to top ]

    Corby,

    To clarify the impact of DI vs AOP here: for dependency injection on Hibernate-hydrated classes, no AOP is necessary. Spring's DependencyInjectionAspectSupport class (currently in the sandbox) does not use AOP but rather just DI via autowiring, despite carrying the term "aspect" in its name.

    So for such a use case, the performance of AOP proxies is completely irrelevant, because there are no AOP proxies involved. It's autowiring overhead there - a completely different beast. Only if you start applying advice to Hibernate-hydrated objects, AOP proxies become involved and cause AOP overhead.

    I personally recommend against applying advice to short-lived objects such as Hibernate-managed persistent instances. Do you have a specific use case here (that you couldn't solve via a net.sf.hibernate.Interceptor)? I'd like to discuss such use cases first, before discussing AOP performance impact on fine-grained objects.

    Juergen
  9. Spring AOP Performance Tuning[ Go to top ]

    So for such a use case, the performance of AOP proxies is completely irrelevant, because there are no AOP proxies involved. It's autowiring overhead there - a completely different beast.

    That's great to hear, Juergen. From an earlier comment by Rod I had misunderstood that DependencyInjectionAspectSupport did indeed require AOP. I will start doing some performance measurements on the additional load of DI on my large application.
  10. Spring AOP Performance Tuning[ Go to top ]

    OK, I think I see where the disconnect is. You are saying that for HIBERNATE-HYDRATED objects, the DI does not require AOP. That is because the DI support in this case is accomplished through the Hibernate Entity Interceptor construct instead.

    However, a lot of my objects are not hydrated through Hibernate (or Spring), and they require the use of something like DependencyInjectionAspectSupport to perform DI. As I understand it, I AM using the AOP framework here, and this puts me back where I started.

    Thanks,
    Corby
  11. Spring AOP Performance Tuning[ Go to top ]

    Well, you will need to pass your custom objects through some sort of initialization mechanism here, to either create them with constructor arguments or initialize them with bean property setters. This still does not involve AOP but rather just a hook in the factory that creates your custom objects.

    Dependency Injection is just an initialization-time mechanism that configures your objects, kicking in through special factories or hooks. AOP via proxies, on the other hand, is a runtime mechanism that essentially intercepts method invocations, which is completely orthogonal to Dependency Injection.

    In other words, there is never a need to create proxies for the purpose of Dependency Injection. DI always applies to the target instance itself. As a consequence, DI does not have an impact on runtime performance of your objects in any way. Only for method interception, i.e. when AOP is actually needed, a proxy needs to be created.

    Juergen
  12. Spring AOP Performance Tuning[ Go to top ]

    Right, so the impact to performance in this case would be determined by the overhead required to autowire a newly hydrated Hibernate domain object using a Spring AutowiareCapableBeanFactory.

    Typically the approach to doing this will be "auto wire by type", which will ask the container to resolve dependencies matching parameter types of setter or constructor arguments on the to-be injected domain object.

    What is the algorithm for this case -- the getBeansOfType(clazz) method, Juergen? Does the factory run through each bean instance looking for a match? Any indexing? I guess, would you view the operation as expensive?

    Keith
  13. Spring AOP Performance Tuning[ Go to top ]

    Keith, all,

    Autowiring by type is indeed a quite expensive operation. DefaultListableBeanFactory's "getBeansOfType" implementation runs through all instances for each call. Note that autowiring by name does not incur such an overhead!

    This doesn't really matter for singletons that get created on startup, but it certainly shows effect for prototypes. We would have to think about special mechanisms to speed this up, for example caching "getBeansOfType" results per given type.

    Juergen
  14. Spring AOP Performance Tuning[ Go to top ]

    Well, you will need to pass your custom objects through some sort of initialization mechanism here, to either create them with constructor arguments or initialize them with bean property setters. This still does not involve AOP but rather just a hook in the factory that creates your custom objects.

    You are assuming here that I control the instantiation of these objects, not some third-party framework. The product I am using only gives me a reference to the object after it has been hydrated (think Hibernate without the Entity Interceptor functionality).

    As far as I can tell, my options boil down to:

    1) Use AOP to DI my objects as they emerge from pre-defined points in the third-party API; or

    2) Manually configure each object as it comes out of the API.

    I am currently using option number 2 because of the performance implications of using option number 1. It works, but it is not real pretty.
  15. Spring AOP Performance Tuning[ Go to top ]

    As far as I can tell, my options boil down to:1) Use AOP to DI my objects as they emerge from pre-defined points in the third-party API; or2) Manually configure each object as it comes out of the API.I am currently using option number 2 because of the performance implications of using option number 1. It works, but it is not real pretty.

    3rd option: How about letting XDoclet generate necessary plumbing code? Just use custom template and let XDoclet create a subclass of API in question.
    I have used this trick and it worked fine.
  16. Spring AOP Performance Tuning[ Go to top ]

    3rd option: How about letting XDoclet generate necessary plumbing code? Just use custom template and let XDoclet create a subclass of API in question. I have used this trick and it worked fine.

    I think I'll pass on XDoclet, but I could still use a similar approach to make things cleaner than they are now. Thanks.

    I would still like to see Spring improve their AOP performance. :)
  17. Spring AOP Performance Tuning[ Go to top ]

    Rob, unrelated to this thread but using this to reach you for a question on your Pro Jakarta Struts book. The book is great, but the only source download thru the apress website appears to be for the First edition title. Does the Second edition have it's own download of source?