Simple Virtual Machines

Terrence Parr presented an interesting introduction to virtual machines. He implemented a simple virtual machine, named appropriately. The code is available in a Java implementation and a C implementation on GitHub. I decided to implement it one of the worst languages you could imagine for such a task: Lua. Lua uses a virtual machine. So we'll have a virtual machine in a virtual machine. Lua doesn't even have an integer type or the switch statement. This means the default word size is actually a double and the dispatch loop is fairly verbose. I tried a number of dispatch methods: an array of functions and a giant if ... else. The array of opcodes is definitely more elegant in Lua but it was slower on my machine.

I created this implementation primarily to see the speed difference between Lua, Java, and C in an intense task. I forked the C version in order to switch to a computed goto. I expected this to offer a performance improvement.

# Calculate factorial(12) 1,000,000 times
# simple virtual machine implementations
luajit:         10.940s [13.7x]
java:            3.114s [3.90x]
c switch:        2.045s [2.56x]
c goto:          0.798s [1.00x]
# other virtual machines
luajit           0.047s [0.06x]
java             0.331s [0.41x] #warm up is long
lua              1.591s [1.99x]
ruby             2.569s [3.22x]
python           4.175s [5.23x]

Performance is as expected. LuaJIT, which seems to compile every opcode, was not as fast as Java. But being a dynamic language, 3.5x slower isn't too bad. Java seems to have a really good JIT compiler. In this case it is only 50% slower than the equivalent C. C only gets much faster when you use ugly optimizations. The computed goto is ugly and non-portable but, as expected, fast. The code for the other languages is on gist.