Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-dev] aj vs aj5 performance issue in client mode

Hi,

   I have a strange performance problem when using aj5 in client mode.

I applied the 'call-count' aspect from DJProf www.mcs.vuw.ac.nz/~djp/djprof to _201_compress bench of JVM98, and I have a surprising results when weaving exactly the same aspect, but running it with aj or aj5.

(I ran 5 times the same bench on the same JVM and calculate the median to discard overhead of instrumentation or classloading). The problem does not happen with -server mode... I tried with jdk1.6 and 1.7, and with aspectj 1.5.4 and 1.6rc2

Client mode:
aj = 20.4 seconds
aj5 = 41.46 seconds!!! (???)

Server mode:
aj = 18.48 seconds
aj5 = 19.74 seconds

 The problem also disappears if I disable JIT...

I dumped the woven code produced by aj and aj5, and it's exactly the same.

I tried with other JVM98 benchs, and I don't have this problem (neither on client or server mode).

The call-count aspect of DJProf uses a HashTable and an int callCount. Similar problem appears if I use a ConcurrentHashMap and an AtomicInteger instead. I also combined ConcurrentHashMap and int counter, and I obtain faster results, but also the execution with aj5 is the double of aj (only in client mode)...

It seems that the JIT is not enabled when using the javaagent used by aj5 or probably some internal caching problem.... I didn't found other reasonable answer to this behavior.

Probably it's related to the type of application, since compress benchmark makes a lot of calculations.


 Any idea what could it be?

Thanks,

Alex

Here is a simplified version of the call-count aspect of DJProf.. if somebody has JVM98 and wants to reproduce the problem...

public final aspect CallCountProfiler {

    static final pointcut allExecs()
        : (execution(* *(..)) || execution(*.new(..)))
        && !within(djprof..*) && !within(CallCountProfiler);

   static private final Hashtable _samples = new Hashtable();

  CallCountProfiler() { }

 before() : allExecs()  {
          getSample(thisJoinPointStaticPart).callCount++;
    }

  Sample getSample(JoinPoint.StaticPart sjp) {

        Sample s = (Sample) _samples.get(sjp);
        if(s == null) {
            s = new Sample(sjp);
            _samples.put(sjp,s);
        }
        return s;
 }

    private final static class Sample implements Comparable {

        public int callCount = 0;

        public final JoinPoint.StaticPart sjp;

        Sample(JoinPoint.StaticPart s) { sjp = s; }

        public int compareTo(Object o2) {
                Sample s2 = (Sample) o2;
                // potential for hashcode collision here
                if(callCount < s2.callCount) { return 1;
                } else if(callCount > s2.callCount) { return -1;
} else if(sjp.hashCode() < s2.sjp.hashCode()){ return 1; } else if(sjp.hashCode() > s2.sjp.hashCode()) { return -1;
                } else { return 0; }
        }
    }
}









Back to the top