With thousands of different mobile devices on the market today, mobile application developers rely heavily on emulators and simulators to sanity-test their apps. As we've said many times before (it's really something of a mantra): there's simply no substitute for hardware testing. We'll be some of the first to tell Android developers (and any mobile developer for that matter) that you must test your mobile application on [at least a good variety of] target devices to ensure that the app works as expected under different conditions, on different hardware and screen types.
We also advocated that developers should use devices, too, so as not to be surprised by differences between the Android emulator and physical devices. ("What you mean devices use slow cellular networks, battery power and have different screen refresh rates?")
Android emulators hold a valuable place in the Android app developer's daily work. It's simply unreasonable to require developers to test on every conceivable Android device configuration these days. Android developers have been able to use the Android emulator, which comes with the Android SDK, to test their applications from the comfort of their development environment. Over time, and many revisions, the emulator has both improved in the features the tool offers, and become bogged down with significant performance problems. By the Honeycomb release timeframe, many Android developers felt that the stock Android emulator had become virtually unusable.
A while back, we were taking part in an Android conference and we ran an informal poll. We asked fellow Android developers what the worst thing about Android development was and what area of Android needed the most improvement. The answers were not about the need for a specific API or some new device feature. Instead, they were overwhelmingly in favor of Android emulator improvements. We basically realized we had a room full of Android app developers begging for a better emulator.
So what exactly was wrong with the emulator? It turned out that few people had complaints about the emulator's features. It wasn't complicated to use. It was reasonably customizable. No, the problem was quite easy to identify: The emulator was slow. And we don't mean go-get-a-cup-of-coffee slow or take-a-bathroom-break slow. We mean "Is this thing still alive? I went to lunch, came back, went to a meeting, came back and it still hasn't loaded." slow. Slow enough to walk, bike or drive down to the nearest big box store, buy a device, activate it, charge it and load up your app, test it and then return it (not that we recommend this practice… usually).
The Android emulator's performance problems only seemed to get worse with the newer and higher resolution emulator configurations, such as those you'd use for current devices with 720p and higher screens. The first few times we tried to load the Honeycomb emulator were downright grueling. By this point, the emulator had become virtually unusable. We talked to some Googlers and asked how they managed to work with the emulators, and everyone was in agreement that there was a lot of room for improvement.
Sure, there were tricks that sometimes worked on certain development environment configurations. For example, developers running Linux seemed to have an easier time of it. However, for many developers, the emulator simply stopped working altogether. We often resorted to using physical hardware for most, if not all, Android app testing and development. This meant returning to the days of constantly searching for devices in the office, charging always-dead batteries, and living with a desktop covered in a nest of cables and chargers. While some of us like having a desk full of devices, it's not necessarily the most productive way to work.
Eventually the Android tools team did indeed turn their attention to improving the emulator's performance. In the last few Android tool revisions, the tools have had significant improvements. The emulator now runs better than it did, but there's still a lot of room for improvement. Meanwhile, others, like Intel®, decided to take matters into their own hands, with some impressive results.
Why Is the Android Emulator So Slow?
If you've used virtual machines in the past, such as the old days of running Windows inside a VM, you'll probably recognize the pain. Most host machines today are based on the x86 instruction set. The system images used by the Android emulator aren't using the same processor type as the host machine. The Android emulator, based on QEMU (the Quick EMUlator), must emulate ARM instructions on top of a different host machine architecture, which is highly processor intensive. QEMU's goal was to deliver speed by supporting new host architectures and not requiring host CPU support for virtualization. Together, all of these things add up to an emulator that works, but can be too slow to be usable.
This real-time translation and simulation at the processor instruction level means that the emulated CPU is, effectively, entirely written in software. In addition to this, other hardware, such as storage, memory, input and output devices must be emulated through software as well. This entire process is what causes the slowdown. In fact, it's a wonder that it works at all. There's an assumption that the software processor works exactly like the real thing, quirks and all. The same goes for the graphics processing, network connection, screen, input and so on.
Early on, when we app developers got our hands on the first Android devices, the emulator had a fairly reasonable task. It had to simulate only a small number of devices, which had very similar stats and hardware. The hardware was also much simpler, the screens of much lower resolution and the performance demands on the host system much less overall. But as the Android device market matured, and different types of devices with very diverse hardware and software specs came on the market, the emulator simply couldn't keep up with being both highly configurable and keep up in terms of performance. The introduction of Android Virtual device profiles, or AVDs, enabled developers to create emulator profiles for a wide variety of devices. The more complex the devices got, the more the emulator ran into trouble.
Intel Improves Android Emulator Performance
There is a solution to all of these performance problems. It does come with a caveat that we'll explain. Recall that the Android platform runs applications inside a VM of its own: the Dalvik VM. As such, the underlying hardware that Android runs on is much easier to change, including the CPU architecture. In fact, there have been devices to ship with an Intel x86 chip instead of the more typical ARM-based chips. Intel has full ported Android over to the x86 architecture.
This matters to Android app developers because it has allowed Intel to distribute emulator system images that are based on the x86 architecture. This alone does not solve the problem of emulator performance, however. In fact, in our testing, by just switching to an x86 system image, a variety of things actually ran slower than when we were using ARM. Until the release of the Intel® Hardware Accelerated Execution Manager (HAXM) driver, that is.
With the Intel® HAXM driver in place, the Android emulator can run the Android system and your apps as fast -- or faster -- than on physical hardware. The speedup is truly dramatic and returns usefulness to the emulator, even running at high resolutions. When combined with GPU emulation -- which helps graphical performance only -- the emulator can now be used again for day-to-day testing (with all of the normal caveats of not using a real device).
There is one catch, for now: Intel's driver requires that your development environment runs on Intel hardware. The solution does, however, run on Windows and Mac OS computers. It's freely available for download. On Linux, KVM is utilized for similar results. (Note: As tested on Intel x86 platforms. AMD platforms are not supported. )
How Does HAXM Speed Up the Android Emulator?
The Android emulator is based on QEMU, which is a virtual machine environment emulating an entire computing system. The HAXM driver support runs both inside the emulator and on the host machine. As with many modern virtual machines, this enables the code inside the emulator to run at nearly full speed on the host machine. A variety of different Intel® Virtualization Technology (VT)-specific features are utilized to perform this feat. (Watch this Intel video for a demo of HAXM and its benefits.)
The interface between QEMU and the HAXM driver on the host system is designed to be vendor-agnostic, but currently it supports only Intel® VT. This means that upcoming Windows machines running on ARM potentially could be supported. In addition, AMD-based x86 machines could also be supported. Naturally, Intel did not do this work for them.
The QEMU support for HAXM was introduced in Release 17 of the Android Development Tools (ADT). The solution has been fully tested to work with Intel x86 images for Android 2.3.7 (API Level 10) and Android 4.0.4 (API Level 14) and higher. In fact, it has passed the Android Compatibility Test Suite.
The overall performance is also increased through efficient use of the host GPU device. This is separate from HAXM, but helps increase performance. A flag can be enabled on each AVD that effectively pushes the 3D commands out to the host machine GPU. You'll see how to enable this in the next section.
Configuring Your Android Development Environment for HAXM
Are you sufficiently enticed? We were! OK, to be honest, it seemed like Android emulator performance could only get better, so let's talk about how you can configure your development environment and start using the HAXM driver to enable the emulator to start pulling its weight again.
Before you begin, make sure your development machine has an Intel CPU in it (such as a Core i7). The HAXM driver and Intel x86 Atom system images are provided by Intel without additional cost, so this isn't a surprise to us. (In fact, we have desktops with competing processors where we can't use this. Even though they are faster for other things, the emulator performance makes our laptops with Intel processors work very well.)
1. Update Eclipse: Make sure your Eclipse installation and the ADT plug-in are fully up to date. At the time of this writing, each was on release version 22.3.
2. Update your Android Tools: After each Eclipse plug-in update, it is important to update your Android SDK Tools. To do this, launch the Android SDK Manager and update all the Android SDK components. To take advantage of HAXM, you must be on at least release version 17.
3. Download the x86 Atom System Images: Using the Android SDK Manager, download the Intel x86 Atom System Image packages for the API Levels you require. As of this writing, system image packages are available only for API Level 10 (Gingerbread MR1 -- Android 2.3.7) and API Level 15 (Ice Cream Sandwich MR1 -- Android 4.0.3/4.0.4) and up, with the recent exception of API Level 19 (KitKat -- Android 4.4) as it was just released. We expect the Intel x86 Atom System Image for API Level 19 at any time.
4. Download the Intel Hardware Accelerated Execution Manager Driver: Again, use the Android SDK Manager to download the HAXM driver. Unlike many other items you can download through the Android SDK Manager, the HAXM driver will not be automatically installed on your computer. Instead, it just downloads an install package that you must install manually.
Alternately, download Intel's Android Tool Suite, codenamed Beacon Mountain, which Includes HAXM and a number of other tools helpful to Android development. For more information, see http://www.developer.com/ws/android/development-tools/intel-tools-for-the-android-developer.html and http://software.intel.com/en-us/vcsource/tools/beaconmountain. The Intel HAXM driver is installed during installation of the suite (skip the next step).
5. Install the HAXM Driver: (Skip this step if you installed Beacon Mountain.) Find the IntelHaxm.exe file within the /extras/intel/Hardware_Accelerated_Execution_Manager folder of your Android SDK installation. Launch the executable to start the installation process. The installer will check your platform configuration for compatibility and then either install the driver or display a failure message if your computer is not compatible with the HAXM driver.
6. Create a New x86 AVD: Using the Android Virtual Device Manager, create a new AVD that will leverage the driver. Most VD settings can remain as you need them. Set the AVD Target property to one of the API Levels that your system has an x86 system image available (API Level 10 or 15+). Choose Intel Atom (x86) as the CPU/ABI. Under Emulation Options, check "Use Host GPU." Verify the rest of the settings are to your liking. When done, click OK to save this AVD profile for use with the emulator. (Note: When you enable GPU emulation you cannot use the AVD snapshot feature. Soon you'll see that it's not nearly as important as it was.)
Now your development environment is ready to rumble with hardware accelerated emulation. Go ahead and launch the emulator using your newly created AVD. You should see a small window titled "Starting Android Emulator." Within it, some status text will show. If you see "HAX is working and emulator runs in fast virt mode" then you'll know everything is installed and working correctly. If, instead, you see "emulator:Failed to open the HAX device!" or "HAX is not working and emulator runs in emulation mode," then the installation did not work properly. At this point, recheck that you followed all the steps for installing everything properly, and that you are targeting compatible API levels in your AVD.
You can also consult the "Configuring Virtual Machine Acceleration" section of the official Android emulator documentation for instructions on setting up HAXM.
So, How Much Faster Is My Android Emulator?
Well, like we said, Android emulator performance couldn't get much worse. But how much better does the emulator perform once you've gotten HAXM on the case? Believe us, you'll notice.
The performance improvements once HAXM is in use can be felt immediately. From the first run, you'll enjoy a much faster bootup time when you launch an emulator instance and once running, the emulator is transformed from a clunky, janky mess (watch this video for a description of jank) to a pleasant experience with silky smooth animations. But these are just subjective observations we had. We decided to run a few performance tests in order to demonstrate and quantify the sorts of improvement that we were experiencing.
Finding easy-to-use benchmarking tools that run through completion on the emulator sounds easier than it is. We ultimately chose to measure boot up time and determine SunSpider 0.9.1, Linpack, and Scimark scores. We also ran some 2D and 3D measurements, but their results aren't standard so we'll just talk about them in general rough terms. Developer.com commissioned us to run all these benchmarks, but note that you can now run the Octane Benchmark for Chrome within HAXM as well.
The first measurement, and probably the one we've all felt the most pain with (and complained the most about), is emulator bootup time. This is the time from when you first tell your development environment to launch the emulator to the time the UI is functionally available to use and you can install apps. We've noted that the first time an Android AVD boots up in the emulator it takes longer to start. We included these numbers, too.
As you can see in the chart, the bootup time is dramatically reduced in both the first bootup time and subsequent bootup times when HAXM is leveraged. Overall, the emulator becomes useful in about a quarter of the time that it used to and about a third of the time an ARM emulator boots up. This is remarkable and can increase developer productivity substantively.
Next we used Vellamo, which utilizes a number of other benchmarks. Specifically, the Dhrystone and Linpack numbers are interesting and revealing.
As you can easily visualize here, the computational benchmarks show a substantial improvement when HAXM is used. While the exact numbers and even the exact differences are not particularly important, what is important is that the improvement is very real. The feel of the emulator and the speed with which your apps will run is all much more on par with current generation high-end device hardware. In fact, as you can see in the results, the accelerated emulator is up to 6x faster than real hardware and still faster than one of the fastest handsets available today.
Finally, we compared browser performance. Some developers may just be using the emulator to test browser code. Is HAXM still worthwhile? You be the judge.
Here again, we also included two devices, an x86 based tablet and an ARM-based phone, and show just relative numbers. Once again, we see that HAXM not only is substantially faster than the regular ARM emulator, but it also has a large lead of current devices. For testing correctness of an application, this is fantastic. For testing the performance of a browser app, you'll still want to test on real hardware. The results here show that the HAXM emulator performance is too good.
Overall, we are quite impressed with the performance results with HAXM. We can only hope other host targets will be added in a timely fashion and, eventually, all API Levels will have an x86 system image available immediately upon release, and that this level of performance ultimately becomes the default on supported development environment configurations.
Is There a Catch?
Like all development configuration decisions, you've got to weigh the pros and cons of using a tool. The HAXM solution isn't too good to be true; there are some downsides. First of all, this solution works only in Intel CPUs at this time. They are the most popular, but there are competing processors that many people use, including these authors. Second, HAXM works only when using an x86 system image. This isn't a huge problem for most developers, because standard Android applications run within the Dalvik VM. Finally, not all Android API levels have x86 system images available. You may have to wait several weeks after the release of a new API level and you may not be able to use x86 images on old API levels. For day-to-day testing, though, we find the support sufficient.
The authors have run into some stability issues during testing. Unfortunately, these stability issues result in host system crashes on Windows 8.1. Fortunately, Intel has provided a hotfix. For more information see http://software.intel.com/en-us/forums/topic/475129. To download the hotfix, see http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager-end-user-license-agreement-windows-hotfix.We would not let this discourage anyone from using HAXM. In fact, the speed at which a fix was provided shows us that Intel is actively supporting their tools and the community.
If you've been losing sleep over how dismal the performance of the Android emulator has gotten as we have, you should be pleasantly surprised by how much Intel's Hardware Accelerated Execution Manager (HAXM) driver improves your work day. If you have a development machine with an Intel processor, we see no reason at all to not use this solution for Android app development. In fact, it's so compelling that we feel it should be the default setup for compatible development environments.
Have you suffered Android emulator performance frustrations too? How have you dealt with them? Share your experiences in the comments below. After you get HAXM up and running, let us know how well it works for you as well. Did you run across any problems with any of your applications? Is it so fast that you have to run your app on the real device to truly simulate the true (slower) performance that users will experience?