1 2 Previous Next 19 Replies Latest reply on Dec 20, 2002 2:37 AM by juhalindfors Go to original post
      • 15. Re: Invokers, AOP and performance
        miffel

        > I am assuming that Rickard's implementation is also
        > done with Dynamic Proxies, so this argues heavily in
        > favor of using a DP-only approach.

        You're right. Rickard is using dynamic proxies.

        • 16. Re: Invokers, AOP and performance
          marc.fleury

          I was thinking about that last night on a comment that Bob Lee already does direct calls to the target instance if there is no interceptors. That means that there is no reflection at all (!!!) so it is pretty obvious to me that we can do a full pointcutting on a system (doing away with a lot of XML) since a sane bytecode implementation will really speed up reflection itself.

          What this means is that as we move further we may in fact go away from Dynamic Proxies. What is neat there is the capacity to add interfaces which is something that we don't easily do at runtime with the classloading.

          • 17. Re: Invokers, AOP and performance
            bill.burke

            > I was thinking about that last night on a comment
            > that Bob Lee already does direct calls to the target
            > instance if there is no interceptors. That means
            > that there is no reflection at all (!!!) so it is
            > pretty obvious to me that we can do a full
            > pointcutting on a system (doing away with a lot of
            > XML) since a sane bytecode implementation will really
            > speed up reflection itself.
            >
            > What this means is that as we move further we may in
            > fact go away from Dynamic Proxies. What is neat
            > there is the capacity to add interfaces which is
            > something that we don't easily do at runtime with the
            > classloading.

            I think we will still want Dynamic Proxies for remote Aspects.

            As far as adding interfaces goes, we will be adding that feature in the near future. You will be able to attach interfaces (and their implementing objects) to regular POJOs.

            Bill

            • 18. Re: Invokers, AOP and performance

              What's wrong with DP today is I have no way of getting an implicit reference to the object that initiated the call. So I either have to explicitly pass my reference to each proxy invocation, or go through mechanisms like SecurityAssociation.

              Today DP is a one way street and that sucks when trying to build the client context into the invocation. There are rather straightforward solutions to this but as far as I can tell they involve the 'weaving' of the class on the caller side (implicitly pushing local zero slot into JVM operand stack). This gives me tremendous expressive power as a programmer but is lacking in java.lang.reflect.Proxy today.

              But this is not my main concern with DP + interceptor stack approach (although a solution seems necessary to cleanly solve the next). It's the propagation of that client context across object instances to the intended target transparently.

              So when I have this:

              (C)||| ==> (O) ==> (O) ==> |||(T)

              Where
              (C) is caller
              (T) is target
              (O) is any 3rd party object unaware of the aspect framework

              Then how do I get that context to implicitly pass through the objects in the middle to the intended target?

              This is very easy to do in AspectJ, what is your alternative in JBoss-AOP?

              • 19. Re: Invokers, AOP and performance


                > I saw some statement over at JBoss forums that
                > using interceptor chains produces overhead that is
                > not insignificant. Since we use interceptor chains in
                > our AOP implementation, so I decided to try this
                > hypothesis and added 50 no-op interceptors to a
                > method and invoked it 100k times to see what the
                > actual overhead was.
                >
                > Without those interceptors the overhead is about
                > 0.009ms/call with JRockit 7 on my system (1.7GHz).
                > With the interceptors the overhead is about
                > 0.012ms/call, so it's an increase of 0.003ms/call. I
                > guess it depends on how paranoid one is about
                > performance, but to me that's quite acceptable.
                > Typically there's about 3-10 interceptors on any
                > given method, so the overhead is going to be even
                > less in the normal case. What really can make things
                > go slow is if those interceptors are poorly coded so
                > that what they do take a lot of time. That's the real
                > (potential) problem AFAICT

                >
                > I am assuming that Rickard's implementation is also
                > done with Dynamic Proxies, so this argues heavily in
                > favor of using a DP-only approach.

                Microbenchamrks aside (I don't trust them -- who's to say JRockit did not just optimize away 100 no-op interceptors, stateless objects, only call going outside is to another instance of the same type itself, no field access. Use an interpreter and look at the difference in percentages if you want to benchmark).

                Conclusion is correct however, any interceptor implementation will be the overwhelming factor in the performance. What is my concern is the numbers of interceptors we might have to have per object to support context passing across object boundaries for instance. And what performance impact will that have.


                > Also, benefitting from Rickard's experience since he
                > has already taken a go at this, he warns that the
                > potential performance bottleneck is in instantiation
                > of the Invokers:

                In any framework where runtime byte code generation is used this is by far the biggest time consumer (at least my experience with BCEL). If you're forced to do the generation inside a loop then it's just murder. Ugly.

                There should be workarounds to this, well-known such as pooling. Of course, as with all pools, then you need to have a good look at how/where the state is stored and deal with that. Depending on the framework the instance state may or may not become an issue.

                After you've dealt with the bcode stuff then the object creation per invocation is the factor. (This is one of the advantages compile-first has over runtime generation -- you don't need to deal with the performance impact. Generation is only required when you need to add new behavior at runtime. Cool as this feature is, it is the exception case. Although it is solvable, it is still up to the programmer to understand the internal working of the framework and understand to force the generation before entering performance critical code).


                > Try running a simple testcase that creates a
                > thousand objects and invoke them. How many objects
                > are created as a side-effect of those invokes? It
                > needs to be close to the number of invocations, e.g.
                > as in my case only the method argument array is
                > created. Otherwise the GC goes crazy and the whole
                > thing will stutter badly.

                1 2 Previous Next