Monday, January 24, 2011

Java byte code generation

To speed up template processing for our template engine I recently decided to optionally compile each template into byte code.

Looking for a library to help me I chose ASM, because it
  1. is small with no dependencies
  2. has been released lately
  3. has decent documentation
  4. has a tool (Eclipse plugin) that generates ASM API calls from existing byte code
Especially no 4 inspired me to do the following:
  1. Create a fistful of hand crafted Java classes that do the same as some selected templates
  2. Create ASM code that generates the same byte code as those Java classes by the tool described in no 4
  3. Create a recursive descent compiler that calls the generalized ASM code derived from step 2 that generates the desired byte code
  4. Load and cache the classes at runtime
It turned out to be a pretty viable approach and allowed me to finish my task without too much knowledge of Java byte code. And what I had to learn anyway was quite enlightening :)

Even though a lot of code remains to be dynamic, because I do not know what will be in the model at run time, the caliper micro benchmarks comparing uncompiled reference code against the compiled version shows a 2.5x - 10x speedup:


benchmark ns logarithmic runtime
SimpleExpressionReference 3367 ================
SimpleExpressionCompiled 963 ==
ComplexExpressionReference 6721 =======================
ComplexExpressionCompiled 1331 ======
If 7067 =======================
IfCompiled 805 =
Foreach 12796 =============================
ForeachCompiled 5275 ====================

1 comment:

Unknown said...

JAXB used an approach where they'd actually ship a class template and "pipe" it through ASM, replacing the field/class/whatever identifiers on the way.