Android Dalvik VM performance is a threat to the iPhone

Android Dalvik VM performance is a threat to the iPhone

One of the peculiarities of Apple is that they have set themselves down a path where every Apple developer needs to learn Objective-C (and C/C++) to build applications for their platform. The biggest characteristic of Objective-C vs Java is dynamic dispatch. At runtime Objective-C can send arbitrary messages to objects and they may or may not respond to them. This has the nice property that you can write code that is very dynamic and loosely bound but it also has the property that method calls in Objective-C are very slow and the more code that you write in Objective-C instead of in C/C++ the slower your codebase becomes. Up until Android 2.2 (Froyo) the JVM (really a Dalvik JVM for licensing reasons) on the Android platform was playing with one hand tied behind its back. Different from desktop/server Java, the JVM was still an interpreter, like the original JVM back in the Java 1.0 days. It was very efficient interpreter but an interpreter none-the-less and was not creating native code from the Dalvik bytecodes that it uses. As of Android 2.2 they have added a JIT, a just-in-time compiler, to the stack that translates the Dalvik bytecode into much more efficient machine code much like a C/C++ compiler. You can see the results of this in the benchmarks of Froyo which show a 2–5x improvement. As they add more and more JIT and GC features that have appeared in HotSpot, JRockit, etc, you will likely see even more improvements over time — without having to change or recompile the 3rd party developed software.

This wouldn’t be that big a deal if Android software wasn’t already approaching the speed of the Apple iPhone even when running its applications through the interpreter (see the HTC EVO 4G running 2.1). This is likely going to mean that 3rd party developer applications created for Android, running on the same hardware, is going to be faster than the same code written against the Objective-C libraries that Apple provides for the iPhone. You’ll be able to get more done, have smoother user interfaces and all around build more powerful applications easier. A better experience for the user and the developer on Android is a bad thing for Apple.

The final issue that Apple has is that far more people know and need to know Java than Objective-C. Except for their platform, there is no need to ever learn it. The tool chain is much more robust, information is much easier to come by, garbage collection is available, and there are thousands more libraries written in Java than Objective-C and far more portable libraries than are written for C/C++. You might argue that you can always drop down to C/C++ code to make up for the lost performance of using Objective-C (at a significant cost development-wise). You can do that, except places where you need to make a call into Apple’s Objective-C runtime libraries or where you want to write callbacks from those libraries. Those are mostly Objective-C libraries and use the dynamic dispatch mechanism which I showed in 2004 was very much slower than Java. I’d really love to see the whole computer language shootout written with Objective-C calling conventions just to show how much slower it is at that level.

Obviously performance is not the only consideration, but it is a big one. Android has other issues like a fragmented operating system base, hardware feature base and a more complicated user experience. All those things will conspire to hold it back but I think we can see the writing on the wall that Android is going to dominate iPhone market-share wise which will eventually make it a more attractive platform business-wise.

Update: Just so people don’t get the wrong idea, I am a rabid iPhone user and develop for the iPhone first. This blog entry is to call out a threat that Apple should take seriously.

Update 2: Alright, you win. Don’t worry about competing with Google & Android on performance. It probably doesn’t matter that much for the user experience. Especially don’t fix obj_msgSend() with a JIT/LLVM, that would be crazy.