28.1.2016

Last Updated on

Android reflection in general has been considered to be painfully slow. But it is actually not that bad at all! We needed to evaluate performance of Field.set() and Field.get() for your open source project joogar ORM and we were really surprised by the results.

Without reflection are both read and write of object attribute one of the fastest operations in Java. It’s just about copying 4 bytes (8 for 64 bit VM) in memory. It’s hard to imagine that reflection performance could be competitive in this case. You are right, it is not, but let’s compare Field.set() and Field.get() with other common native operations.

Methodology

We created simple Android app with small benchmarks for this 7 operations:

  1. Assign object’s atribute value (object.attribute = value;)
  2. Assign object’s atribute value with reflection (field.set(object, value);)
  3. Read object’s atribute value with reflection (field.get(object);)
  4. Primitive type autoboxing (integerVariable = intVariable;)
  5. String concatenation (stringVariable + intVariable;)
  6. New object creation (new MyClass();)
  7. Logging (Log.i("MyTag", "Log for performance test.");)

Measurements

At first we compared simple value assign with Field.set(). Reflection was 18x slower! That’s a really bad result, which makes it almost totally unusable. We gave it one more chance and compared its performance with other operations we used in object-relation mapping code. Check the table bellow where all values are presented relatively as multiple of native property write time.

HTC One m7 HTC Evo 3D Nexus 7 2013 LG G3
Android 4.4.3 4.0.3 5.0.0 5.0.0
Native write 1x 1x 1x 1x
Reflection write 20x 32x 31x 71x
Reflection read 23x 34x 14x 31x
Autoboxing 133x 140x 26x 64x
Concat 897x 1 046x 119x 259x
Object 158x 172x 22x 64x
Logging 602x 607x 728x 1 289x

As you can see, the performance of reflection Field.set() and Field.get() is very similar. Very slow reflection write on LG G3 is quite surprising – maybe some hardware related issue?

Autoboxing is very slow on Dalvik, but little faster than reflection on ART. As for ART we can state that having autoboxing in your code is very similar to using Field.set() or Field.get(), for Dalvik we can consider Autoboxing to be 4x – 7x slower than reflection attribute write/read. Not bad results for reflection.

String concatenation is a real performance killer! Concatenation is 4-8x faster on ART but still significantly slower than read/write reflection. You should be really careful with it and use StringBuilder when possible.

Creating new Object is very similar to Autoboxing. Not surprisingly, internally it has to be almost identical operation.

Another performance killer is logging. It is 18x – 30x slower than reflection read/write on both ART and Dalvik. Avoid logs in production code!

Conclusion about reflection

Reflection is much more slower than compiled code. There is no discussion about that but compared with other trivial operations it is not that serious. Use reflection with care and measure its impact on your code performance, if you write time-critical part of your app. When compared with other standard Java constructs reflection is not a performance killer, it is just a little bit slower than native code.

Source code for test app

Vladislav Skoumal
SKOUMAL CEO