Mythbuster: Android annotation performance unravelled

Mythbuster: Android annotation performance unravelled

Over the last few weeks I have been involved in a lot of discussions whether it is justified to use Android frameworks that rely on a lot of annotation processing. There have been several bug reports on annotation performance on the Android issue tracker and numerous posts on Google+ surrounding this topic. The most common candidates to suffer from annotation performance issues are frameworks like RoboGuice or the Otto event bus. Both frameworks are fully annotation driven.

[ Want to develop for several platforms in one go? Check out Tabris – the Java toolkit for the development of native mobile apps: Download 30-day Trial ]

Benchmarking annotations

According to the Android issue #7811 the performance of annotation processing has been much improved in Android 4.0 (ICS) and above. So in order to compare the performance between older 2.x devices and 4.0+ i have created a little benchmark which checks if an annotation is present on a type (class), constructor, field, or method. The code for each check looks like this:

<pre lang="java">
private void parseMethod(Class<?> type) {
  start = System.currentTimeMillis();
  Method[] methods = type.getMethods();
  for (int i = 0; i < methods.length; i++) {
    Method method = methods[i];
    if (method.isAnnotationPresent(Benchmark.class)) {
      // do something
    }
  }
  timeMethod += System.currentTimeMillis() - start;
}
</pre>

The benchmark runs the test 100.000 times and the graphs show the results of 10 consecutive runs averaged out. The tests were performed on two Samsung Galaxy S2 devices as well as on ARM based emulators. The S2 devices were running Android 2.3.4 and 4.0.4. Here are the results for the Galaxy S2:

 

The results we see are a little bit surprising. Checking for an annotation on a class and a constructor has improved dramatically. Method checking got a little worse but more astonishing, the time it takes to check on a field has increased dramatically. The jump is not that huge in absolute numbers but in relation to 2.3.4 the performance has dropped dramatically for field annotations.

When we look at the charts for the emulator performance we see a pretty similar picture:

Type and constructor performance has increased, method performance went down a bit but field checking has become a costly operation.

What is the cause for that? At that point it is hard to tell. During the execution of the benchmark all devices generated a huge amount of objects. The garbage collector was constantly running. The reason for the garbage collection is the use of .toString() in the .equals() method of Method, Constructor etc instances. So there are definitely ways to improve performance as pointed out here.

Conclusion

What does it mean for annotation based frameworks? Usually the most annotations are placed on exactly the kind of elements where the performance has decreased. Therefore switching to Android 4.0 will not improve your applications performance when relying on these kind of frameworks. If you only use type and constructor annotations you will see a dramatic improvement.

The annotation discussion also hoovers around the question: “Will you experience performance problems with RoboGuice on Android 2.x devices?” Judging from the benchmarks the answer would be: No. You will probably not use that many annotations that you will feel a serious performance impact in any version of Android. If you do, Android 4.0 won’t save you.

Footnote

Just for comparison sake: Here are the benchmark results for the Galaxy Nexus and the Nexus 7:

As expected the Nexus 7 is faster than the Galaxy Nexus.

No Comments

Post a Comment

Comment
Name
Email
Website