During a recent discussion, I had the need to show some numbers demonstrating why Deelang needs the new DEX compiler. As I said in that thread, it’s all about removing reflection from the compiled classes.
We all know that “reflection is slow” (for some value of slow) and especially on Android, that it isn’t generally a good solution for general use in method invocation. Looking up methods by reflection is slow, as is performing the actual invoke. But how slow? Could I quantify the difference?
Since the Deelang DEX compiler is still being actively developed, I’ve never paid much attention to performance before, and have certainly never benchmarked it. We knew that the Dee VM wasn’t fast enough for some of the things we were using it for, and I knew from experience that it would be faster without reflection, and we left it at that. This discussion got me thinking though, and I decided it would be nice to have some idea of the actual difference between the Dee VM and scripts compiled to DEX.
Despite the fact that microbenchmarks are often a bad idea, and are a bit of a minefield at the best of times, I wrote one in this instance. After all, I only want some idea of the comparative performance for the sake of discussion – I won’t actually be basing any design or implementation decisions on these results.
I expected a decent performance boost in the DEX compiled scripts, but I honestly wasn’t quite prepared for how much of a boost:
09-27 10:45:27.525: I/BENCHMARK(15853): Rehearsal 09-27 10:45:37.665: I/BENCHMARK(15853): DeeVM completed : 10000 runs : 10107ms (10.107 seconds) 09-27 10:45:37.725: I/BENCHMARK(15853): Dex completed : 10000 runs : 31ms (0.031 seconds) 09-27 10:45:37.725: I/BENCHMARK(15853): Real 09-27 10:45:46.695: I/BENCHMARK(15853): DeeVM completed : 10000 runs : 8938ms (8.938 seconds) 09-27 10:45:46.745: I/BENCHMARK(15853): Dex completed : 10000 runs : 25ms (0.025 seconds)
(This is logcat from the benchmark running on-device on a HTC One X)
That’s right – almost 9 seconds for the reflection-based Dee VM, compared to 0.025 seconds for the DEX compiled version. The difference is so marked that I at first didn’t believe the results. I changed the script to actually produce some output to logcat, to make sure that it was actually running each implementation properly, and it was. It turns out that, in this case, reflection has a much bigger impact that I expected.
In case you’re interested, you can see the benchmark code at the this page on the project wiki on Google Code.