[
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; }
}
}
}