In any class, if you don't need to access an object's fields, make your method static. Invocations will be about 15-20%
faster. And you can tell other devs that calling the method can't alter the object's state.
In any class, if use static int val = 22
the compiler generates a class initializer method - called <clinit>
, that is executed when the class is first used - to store 22
into val
to access later with field lookup.
If we add the final
keyword like static final int val = 22
this class no longer requires a <clinit>
method, because the constants go into static field initializers in the dex file and can be refered directly later without field lookup.
Note: This optimization applies ONLY to primitive types and String constants, not arbitrary reference types. Still, it's good practice to declare constants static final whenever possible.
foreach
loop can be used for collections that implement the Iterable interface and for arrays, should use it by default because it's faster (with JIT) or equal (without JIT) than normal counted for loop.
But with an ArrayList
, a hand-written counted loop is about 3x faster than foreach loop.
Consider define an inner class (inner class cannot be static) Foo$Inner
that directly accesses private methods/fields in the outer class. This is legal in Java.
But the problem is that the VM considers direct access to Foo
's private members from Foo$Inner
to be illegal because Foo
and Foo$Inner
are different classes. To bridge the gap, the compiler generates synthetic methods:
/*package*/ static int Foo.access$100(Foo foo) {
return foo.mPrivateVal;
}
/*package*/ static void Foo.access$200(Foo foo, int val) {
foo.privateMethod(val);
}
The inner class code calls these static methods whenever it needs to access the mPrivateVal
or invoke the privateMethod()
of the outer class. This is an "invisible" performance hit because accessors are slower than direct field accesses, and it will hurt the 64K methods limit of Android too.
As a rule of thumb, floating-point is about 2x
slower than integer on Android-powered devices.
In speed terms, there's no difference between float and double on the more modern hardware. Space-wise, double is 2x
larger. As with desktop machines, assuming space isn't an issue, you should prefer double to float.
By prefering library code over your own code you can avoid "re-inventing the wheel" and bear in mind that the system is allowed to replace calls to library methods with hand-coded assembler, which may be better than the best code the JIT can produce for the equivalent Java. The typical example here is String.indexOf()
and related methods, which Dalvik replaces with an inlined intrinsic. Similarly, the System.arraycopy()
method is about 9x
faster than a hand-coded loop on a Nexus One with the JIT.
Developing your app with native code using the Android NDK is NOT necessarily more efficient than programming with the Java language.
For one thing, there's a cost associated with the Java-native transition, and the JIT can't optimize across these boundaries. If you're allocating native resources (native heap,..) it's more difficult to arrange timely collection of these resources. You also need to compile your code for each architecture you wish to run on so it will increase APK size.
Native code is primarily useful when you have an existing native codebase that you want to port to Android, not for "speeding up" parts of your Android app written with the Java.
Enum cause bigger apk size, 4 byte reference + enum size. -> Use constants or IntDef instead.