Saturday, December 10, 2011

The truth about Android & iOS UI performance

Some fallacies related to Android vs. iOS UI performance made the rounds recently, inflicting undue damage to Android's reputation. It all started with a misinformed Google+ update written by former Android testing intern Andrew Munn.

Time reporter Matt Peckham echoed Andrew's misconceptions the following day, further spreading the FUD about Android. Toward the end of his article, Matt noted:

I’m not an Android or iOS software engineer, so all I can say in response to any of this is that, assuming Munn’s correctly articulated the way rendering takes places on Android and iOS devices, it makes sense (but then so does the idea that Lee Harvey Oswald had help, at least to some people).

Peckham makes no mention of trying to corroborate Munn's claims with a more experienced, knowledgeable engineer, like Romain or Dianne from the Android team, nor does he reference the corrections made by iOS experts in the comments on Munn's post. A more qualified engineer would support their theories with evidence like code, specifications, and performance test results, not Reddit and Hacker News comments as Munn did.

I don't claim to have all the answers, but I can tell you that implementing fluid interfaces on both iOS and Android is time consuming and difficult. The challenges are an order of magnitude more complex than Munn suggests. I haven't had an opportunity to try Ice Cream Sandwich yet, so I can't tell you firsthand how it compares to the iPhone. However, Jason Kincaid, quoted by Munn, described ICS as quite smooth and noted that both Android and iOS stutter occasionally.

Now that Android has pervasive hardware acceleration, Android has no fundamental technical disadvantage compared to iOS with regard to to implementing fluid UIs. Given comparable hardware, any UI that runs smoothly on iOS should be able to run just as smoothly on Android. That said, hardware acceleration isn't a magic switch that you can just turn on. Android developers need to modify their applications to take full advantage, just like iOS developers have to design their own applications with hardware acceleration in mind. This will take time.

To Munn's point, "UI thread" and "main thread" mean the same thing. Most user interface frameworks, including those employed by iOS and Android, have a notion of receiving input events and manipulating the user interface from a single thread. Users of those frameworks often use the terms "UI thread" and "main thread" interchangeably. Why impose this restriction? If you limit access to UI elements to a single thread, you simplify API usage and improve performance because you don't have to deal with locks and concurrency. Contrary to Munn's claims, Android does actually assign a higher scheduling priority to the UI thread than it does to background threads. I assume iOS does likewise.

Android and iOS are more alike than different in this respect. Either platform will hang and stop responding to user input if you monopolize the main thread with blocking operations (like file I/O) or slow drawing logic. This likely explains why Jason experiences jitters when visiting global search on iOS. On both platforms, programmers should perform all blocking operations on background threads and should never block the main thread.

As for the differences, iOS's Core Animation framework tweens animations in a background thread while Android does the same in the main thread. On iOS animations continue running, even when the application accidentally blocks the main thread. In addition, when scrolling, iOS's main thread goes into a "tracking" mode where it filters out certain types of events that might result in redrawing or other performance degradations. This has no affect on background operations. Nothing technically prevents Android from supporting these features, but their absence doesn't preclude smooth UIs on Android either. Hardware acceleration is far more important.

Does this mean we're going to start seeing iOS-quality user interfaces across the board on Android in the near future? No way. The reasons have little to nothing to do with bytecode or garbage collectors and everything to do with the community and tools. First, iOS app developers have far more experience taking advantage of hardware acceleration. They're experts in going out of the way to avoid software rendering. Hardware rendering requires a different mindset, and Android programmers will need time to catch up.

Second, Android programmers need to support both software and hardware rendering for awhile. This requires more code. Some Android devices support only software rendering while others, like the Xoom, actually require hardware rendering to achieve any semblance of smooth animation. Developing and maintaining smooth Android apps will require significantly more developer resources than accomplishing the same on iOS, at least until we can retire support for pre-Honeycomb devices. Programmers with limited resource will no doubt have to elide animations and settle for lowest common denominator solutions for awhile.

Third, from what I've seen, iOS developers have far better tools at their disposal. iOS developers can tweak and reload their applications in seconds, faster than you can reload a Ruby on Rails web page, while Android developers are lucky to do the same in tens of seconds. Being able to quickly iterate and tweak a UI is essential to achieving pixel-perfect, high frame rate animations. If Android programmers need to wait up to a minute after each tweak, they'll be at a significant disadvantage compared to their iOS counterparts. iOS provides amazing tools that overlay their UIs and help pinpoint and eliminate software rendering. In contrast, the UI performance and bugs in Android's emulator are so bad that developers resort to running on real devices only, even during development.

Android's training and legacy support issues will resolve themselves eventually. If I ran the Android team, I'd triple down on tool support. Android's emulator sounds great in theory, but it fails spectacularly in practice. Professional Android programmers simply can't and don't use it. Frankly, the emulation model is a lost cause. Android should replace it with an iOS-like simulator, one with tightly integrated profiling tools, capable of building and displaying apps in seconds. Ideally, the development build process would further cut down the turnaround time by eliding resource compilation, dex conversion, etc.

In the meantime, Android developers can achieve buttery user interfaces on Honeycomb and ICS devices, just like their iOS equivalents, by eliminating blocking operations from the main thread, minimizing time spent drawing in software, and allocating objects judiciously. Android programmers just have to work a little longer and harder to get there. Given our fierce dedication to a flawless user experience, my team plans to invest the necessary resources and accomplish just that. If you think you're up to the challenge, please apply.

For additional reading, Dianne has done a wonderful job explaining why the Android team made the choices they did and how those choices enabled some unique advantages over iOS.