On Sun, 2 Dec 2012, shannah wrote:
> Hi Joel,
> I have just finished setting up a port of CodenameOne using Avian for IOS.
> ï¿œThe current default port uses XMLVM, and it was my hunch that the
> performance of XMLVM wouldn't be as good as Avian since it is having to
> convert all code into stack operations in C. ï¿œHowever, I set up a simple
> benchmark to compare my Avian build with the same application converted with
> XMLVM, and XMLVM actually out performed Avian.
> The benchmark was to run the towers of hanoi. ï¿œI ran it with n=30 moving
> from pole 1 to pole 3 on my iPhone 4S and found that XMLVM would complete in
> approx 35 seconds vs Avian 43 seconds.
>
> Given your intimate knowledge of how Avian works, do these results make
> sense to you? ï¿œShould avian AOT be approaching raw C code performance or are
> there factors that affect performance? ï¿œCan you suggest things that I can do
> to try to improve the performance?
I can't comment much on how XMLVM works, but if it translates to C it can
in theory take advantage of the optimizations provided by the native C
compiler for the target platform.
Avian's AOT compiler is really just its JIT compiler run ahead of time,
and the JIT compiler is not very sophisticated. It doesn't do method
inlining, loop unrolling, autovectorization, code motion, intellegent
register allocation, etc. -- all of which modern C compilers like GCC and
LLVM are really good at. So, no, Avian would give you "raw C code"
performance when compared to a good C compiler.
ProGuard can help bridge the gap in theory, since it's capable of doing
many of the optimizations mentioned above on the Java bytecode before
Avian even sees it. However, I've had to disable optimization in e.g. the
hello-ios example because ProGuard crashes otherwise. I've tried to
reduce it to a simple test case so I could submit a useful bug report to
the ProGuard maintainer, but I haven't succeeded yet. If you've got the
time and the interest, you might want to give that a shot. You can start
by removing the "-dontoptimize" line from the makefile and see what
happens.
Besides that, my only suggestion is to run a real world test app (e.g. not
towers of hanoi unless that's actually the app you care about) through a
profiler to determine (A) if there really is a performance problem in
practice and (B) which code is the bottleneck. In my code at least, the
performance-sensitive parts are all implemented in native code and/or
dedicated hardware anyway (e.g. audio/video decoding and image scaling),
so the performance of Java code has not generally been an issue.
FWIW, I'm planning to do some work on trace-based JIT compilation in the
future, which will ultimately involve adding more sophisticated
optimizations to the compiler which should also be applicable to AOT
compilation. I can't say for sure whether that's months or years away,
though, since it will be strictly a spare time project, and spare time is
always hard to come by.
If you're really passionate about this, I can give you an overview of how
the JIT compiler works in Avian with an eye towards improving it, but I
must warn you that it is the most obscure and compilicated part of the VM.
I'll admit I didn't even try to make it easy for other people to
understand, so it reads like a raw brain dump and probably only makes
sense if your brain is wired just like mine :)