[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] QUESTION: Optimizing pointcuts for performance

Thanks for your response.
I have included pieces of the actual implementations below to be more clear. I have a little framework for managing the interceptors external to the definitions in AspectJ.

>>Do you need to know who is calling the ctor (if so, where is the binding for who is making the call)?
Can you clarify how this works with an example
>>Do you intend to sometimes replace the object returned from the ctor?
Sometimes
>>Do you use thisJoinPoint?
I use thisJoinPoint to access the parameters

  public pointcut Bootstrap_new() :
      call(Bootstrap+.new(..));

  public pointcut Bootstrap_onInstall(
      Bootstrap object) :
      execution(public void onInstall()) &&
      this(object);

    Object around() :
        Bootstrap_new() {
        logEntering(thisJoinPoint);
        Proceed proceed = new Proceed() {
            public Object invoke(Object target, Object[] args) throws Exception {
                return proceed();
            }
        };
        Object result = null;
        try {
            result = system.invoke(JBIConstants.KEY_BOOTSTRAP_NEW, -- This delegates to my framework, ultimately calling Proceed by default, unless skipped by interceptor in chain
                    thisJoinPoint, proceed);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return result;
    }

    Object around(Bootstrap object) :
        Bootstrap_onInstall(object) {
        logEntering(thisJoinPoint);
        Proceed proceed = new Proceed() {
            public Object invoke(Object target, Object[] args) throws Exception {
                Bootstrap bootstrap = (Bootstrap) target;
                return proceed(bootstrap);
            }
        };
        Object result = null;
        try {
            result = system.invoke(JBIConstants.KEY_BOOTSTRAP_ONINSTALL,
                    thisJoinPoint, proceed);
        } catch (JBIException e) {
            throw e;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }


Andy Clement wrote:
Hi Jason,

> General pointers:

1. 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'.

2. Avoid thisJoinPoint in your advice if you can. It is expensive to create.  If you must use it then try to include an if() guard component to your pointcut so that creation of thisJoinPoint can be conditional.  (This is a better approach than putting an if() condition as the first line in your advice).  The static information available with thisJoinPointStaticPart is not so bad as that is only calculated once at class load time so don't worry if you need to use this.

3. Use within()/withincode() wherever possible to limit the code that is processed looking for join points - don't just rely on specifying the declaring type in, for example, the execution pointcut.  Always try to use within()/withincode().

4. Ordering of components in pointcuts doesn't matter.  There is no need to put your within()s first and your execution()s in the middle and cflows() at the end.  AspectJ rewrites your pointcuts before evaluation ensuring the cheap tests are first and expensive ones last.


> How are within() pointcuts and <... within ...> clauses related?

The include/exclude within clauses in aop.xml are kind of a higher level guard on whether a type should be passed to the weaver.  If it fails to meet the patterns specified in any of the <... within ...> clauses then it will not even be passed to the weaver.  If it is passed then to the weaver then it may be immediately dismissed if it doesn't match a within() pointcut - but there it is slightly more overhead than using the <... within ...> clause.  Implicitly there is an <include within="*"> that means everything will be passed to the weaver, so I wouldn't start using other include within clauses unless you are also using exclude clauses as well.

> Weaving java.* and javax.*

With basic LTW setup, we do not weave types in java.* and javax.* packages.  Getting the weaver associated with the loader for java.* is hard anyway.  So specifying include or exclude within clauses related java and javax are redundant (and introduce overhead).  So unless you are using the -Xset options to weave java and javax types, don't bother with these within clauses.

In addition we don't weave org.aspectj.* and we don't weave sun.reflect.* so you don't need to bother excluding those.

> Using your own message handler

This is fine, but be careful it doesn't introduce overhead.  make sure it is set to ignore messages it is not interested in rather than saying it is interested in everything then ignoring them when it is called with them. Some messages (eg. weave info) are expensive to create.

So on your specific config. 

call().  What context do you collect around a call to a constructor of Bootstrap - why is execution() not OK for you?  Do you need to know who is calling the ctor (if so, where is the binding for who is making the call)?  Do you intend to sometimes replace the object returned from the ctor?  Do you use thisJoinPoint?

execution(). add a within(Bootstrap+).

include/exclude in aop.xml.  per the documentation at http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html
 <aspects>

              <!-- Of the set of aspects declared to the weaver
                   use aspects matching the type pattern "com..*" for weaving. -->

              <include within="com..*"/>

              <!-- Of the set of aspects declared to the weaver
                   do not use any aspects with the @CoolAspect annotation for weaving -->

              <exclude within="@CoolAspect *"/>

</aspects>
<weaver options="-verbose">
              <!-- weave types in someoldpackage and types in the foo package

                   that do not have @NoWeave -->
              <include within="someoldpackage.*"/>
              <include within="(!@NoWeave foo.*) AND foo.*"/>

              <!-- Do not weave types within the "bar" pakage -->

              <exclude within="bar.*"/>
</weaver>

  
I had completely forgotten about the include/exclude section in aspects - I guess I haven't known many people use that...

The only downside with exploiting the include/exclude section in the weaver section is that when developing your aspects in the IDE (with AJDT) it can lead to confusion because compile time weaving ignores those clauses and is just obeying the pointcuts.  We have a forthcoming enhancement to fix the compiler to respect aop.xml files which will help in this regard.

Andy.

2009/1/15 Jason Weinstein <Jason.Weinstein@xxxxxxx>
I have a number of pointcuts which look at lot like these below. I don't know what packages they will be found in. I do know that they will not be in java.* or javax.*. Can someone tell me how best to create the highest performing pointcuts without knowing which packages they will be part of or just other general tips.

Bootstrap is an "interface"

-- note using call
  public pointcut Bootstrap_new() :
      // notwithinThis() &&
      // withincode(* com..*(..)) &&
      call(Bootstrap+.new(..));

-- note using execution
  public pointcut Bootstrap_onInstall(
      Bootstrap object) :           // notwithinThis() &&
      execution(public void onInstall()) &&
      this(object);


My aop.xml file looks like. How does my aop.xml affect the weaving (LTW).

<aspectj>
  <aspects>
      <aspect name="mypackage.MyAspect" />
      <!--
          <include within="com..*"/> -- WHAT MIGHT THESE DO?
          <include within="java..*"/>
          <include within="javax..*"/>
          <include within="org..*"/>
      -->
  </aspects>
  <weaver options="-XmessageHandlerClass:mypackage.AspectJMessageHandler">
      <!--
          <include within="java..*"/> -- WHAT MIGHT THESE DO?
          <include within="javax..*"/>
          <include within="org..*"/>
          <include within="com..*"/>
          <exclude within="mypackage.*"/>
      -->
      <!--
          <dump within="java..*"/>
          <dump within="javax..*"/>
          <dump within="org..*"/>
          <dump within="com..*"/>
      -->
  </weaver>
</aspectj>
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users


_______________________________________________ aspectj-users mailing list aspectj-users@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/aspectj-users