Android Code Optimization Techniques

26
RESTRICTED MORPHO MORPHO RESTRICTED This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho. Android Code Optimization Techniques (Session 1) 06/11/2014

Transcript of Android Code Optimization Techniques

Page 1: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

Android Code Optimization Techniques(Session 1) 06/11/2014

Page 2: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

2 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

AGENDA

You should use the tips in this document as general coding practices that you can incorporate into your habits for general code efficiency.

In this training we will take just an overview of code efficiency.

In this session we will discuss only class constructor in deep.

CONFIDENTIAL / February 2014 / CEE - CC India

Page 3: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/01/Rules for writing efficient code

Page 4: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

4 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

RULES FOR WRITING EFFICIENT CODE

There are two basic rules for writing efficient code Don't do work that you don't need to do.

E.g File file=new file(“myFile.txt”);

public boolean isFileExist(){if(file.exist){

return true;}else

retrun false;/// return file.exist;

}

Don't allocate memory if you can avoid it.E.g String home = new String(“Home”); It will create a new object on every call.String home=“Home”; consider a for loop then this would be 250 times faster then above.

CONFIDENTIAL / February 2014 / CEE - CC India

Page 5: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/02/About Creating Objects

Page 6: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

6 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

ABOUT CREATING OBJECTS

Avoid Creating Unnecessary Objects Object creation is never free. As you allocate more objects in your app, you will force

a periodic garbage collection, creating little "hiccups" in the user experience

Thus, you should avoid creating object instances you don't need to. Some examples of things that can help:

If you have a method returning a string, and you know that its result will always be appended to a StringBuffer anyway, change your signature and implementation so that the function does the append directly, instead of creating a short-lived temporary object.

An array of int is a much better than an array of Integer objects, but this also generalizes to the fact that two parallel arrays of ints are also a lot more efficient than an array of (int,int) objects. The same goes for any combination of primitive types.

If you need to implement a container that stores tuples of (Foo,Bar) objects, try to remember that two parallel Foo[] and Bar[] arrays are generally much better than a single array of custom (Foo,Bar) objects. 

CONFIDENTIAL / February 2014 / CEE - CC India

Page 7: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/03/Prefer Static Over Virtual

Page 8: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

8 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

PREFER STATIC OVER VIRTUAL

If you don't need to access an object's fields, make your method static. Invocations will be about 15%-20% faster. It's also good practice, because you can tell from the method signature that calling the method can't alter the object's state.

CONFIDENTIAL / February 2014 / CEE - CC India

Page 9: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/04/Use Static Final

Page 10: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

10 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

USE STATIC FINAL

Use Static Final For Constants Consider the following declaration at the top of a class:

We can improve matters with the "final" keyword:

CONFIDENTIAL / February 2014 / CEE - CC India

static int intVal = 42;static String strVal = "Hello, world!";

static final int intVal = 42;static final String strVal = "Hello, world!";

Page 11: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/05/Internal Getters/Setters

Page 12: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

12 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

INTERNAL GETTERS/SETTERS

Avoid Internal Getters/Setters In native languages like C++ it's common practice to use getters (i = getCount())

instead of accessing the field directly (i = mCount). This is an excellent habit for C++ and is often practiced in other object oriented languages like C# and Java, because the compiler can usually inline the access, and if you need to restrict or debug field access you can add the code at any time.

However, this is a bad idea on Android. Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.

Direct field access is about 7x faster than invoking a trivial getter.

CONFIDENTIAL / February 2014 / CEE - CC India

Page 13: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/06/Loop Syntax

Page 14: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

14 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

USE ENHANCED FOR LOOP SYNTAX

static class Foo {    int mSplat;}

Foo[] mArray = ...

public void zero() {    int sum = 0;    for (int i = 0; i < mArray.length; ++i) {        sum += mArray[i].mSplat;    }}

public void one() {    int sum = 0;    Foo[] localArray = mArray;    int len = localArray.length;

    for (int i = 0; i < len; ++i) {        sum += localArray[i].mSplat;    }}

public void two() {    int sum = 0;    for (Foo a : mArray) {        sum += a.mSplat;    }}

CONFIDENTIAL / February 2014 / CEE - CC India

• zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the loop.

• one() is faster. It pulls everything out into local variables, avoiding the lookups. Only the array length offers a performance benefit.

• two() is fastest for devices without a JIT, and indistinguishable from one() for devices with a JIT. It uses the enhanced for loop syntax introduced in version 1.5 of the Java programming language.

Page 15: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/07/Avoid Using Floating-Point

Page 16: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

16 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

AVOID USING FLOATING-POINT

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.

CONFIDENTIAL / February 2014 / CEE - CC India

Page 17: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/08/Know and Use the Libraries

Page 18: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

18 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

KNOW AND USE THE LIBRARIES

The typical example here is String.indexOf() and related APIs, 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.

CONFIDENTIAL / February 2014 / CEE - CC India

Page 19: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

/09/CLASS CONSTRUCTOR

Page 20: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

20 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

MANAGE MULTIPLE CONSTRUCTOR PARAMETER

Consider a builder when faced with many constructor parameters

Traditionally, programmers have used the telescoping constructor pattern, in which you provide a constructor with only the required parameters, another with a single optional parameter, a third with two optional parameters, and so on, culminating in a constructor with all the optional parameters.

CONFIDENTIAL / February 2014 / CEE - CC India

Page 21: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

21 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

TELESCOPING CONSTRUCTOR PATTERNpublic class NutritionFacts { private final int servingSize; // (mL) required

private final int servings; // (per container) requiredprivate final int calories; // optionalprivate final int fat; // (g) optionalprivate final int sodium; // (mg) optionalprivate final int carbohydrate; // (g) optional

public NutritionFacts(int servingSize, int servings) {this(servingSize, servings, 0);

}

public NutritionFacts(int servingSize, int servings, int calories) {this(servingSize, servings, calories, 0);

}

public NutritionFacts(int servingSize, int servings,int calories, int fat) {this(servingSize, servings, calories, fat, 0);

}

public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) {this(servingSize, servings, calories, fat, sodium, 0);

public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {this.servingSize = servingSize;this.servings = servings;this.calories = calories;this.fat = fat;this.sodium = sodium;this.carbohydrate = carbohydrate;

}

When you want to create an instance, you use the constructor with the shortest parameter list containing all the parameters you want to set:

NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);

CONFIDENTIAL / February 2014 / CEE - CC India

In short, The telescoping constructor pattern works,but it is hard to write client code when there are many parameters, and harder still to read it.

Page 22: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

22 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

JAVABEANS PATTERNWHEN FACE MANY CONSTRUCTOR PARAMETERS A second alternative, is the JavaBeans pattern, in which you call a

parameterless constructor to create the object and then call setter methods to set each required parameter and each optional parameter of interest:

public class NutritionFacts {// Parameters initialized to default values (if any)private int servingSize = -1; // Required; no default valueprivate int servings = -1; // " " " “private int calories = 0;private int fat = 0;private int sodium = 0;private int carbohydrate = 0;

public NutritionFacts() { }

// Setterspublic void setServingSize(int val) { servingSize = val; }public void setServings(int val) { servings = val; }public void setCalories(int val) { calories = val; }public void setFat(int val) { fat = val; }public void setSodium(int val) { sodium = val; }public void setCarbohydrate(int val) { carbohydrate = val; }

It is easy, if a bit wordy, to create instances, and easy to read the resulting code:NutritionFacts cocaCola = new NutritionFacts();cocaCola.setServingSize(240);cocaCola.setServings(8);cocaCola.setCalories(100);cocaCola.setSodium(35);cocaCola.setCarbohydrate(27);

CONFIDENTIAL / February 2014 / CEE - CC India

Unfortunately,The JavaBeans pattern has serious disadvantages of its own.Because construction is split across multiple calls

Page 23: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

Telescoping constructor pattern is safe

JavaBeans pattern has more readability

Luckily, there is a third alternative that combines the safety of the telescoping constructor pattern with the readability of the JavaBeans pattern. It is a form of the Builder pattern

Page 24: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTED

24 /

This document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

BUILDER PATTERNpublic class NutritionFacts {

private final int servingSize;private final int servings;private final int calories;private final int fat;private final int sodium;private final int carbohydrate;

public static class Builder {// Required parametersprivate final int servingSize;private final int servings;

// Optional parameters - initialized to default valuesprivate int calories = 0;private int fat = 0;private int carbohydrate = 0;private int sodium = 0;

public Builder(int servingSize, int servings) {this.servingSize = servingSize;this.servings = servings;

}

public Builder calories(int val) { calories = val; return this; }public Builder fat(int val) { fat = val; return this; }public Builder carbohydrate(int val) { carbohydrate = val; return this; }public Builder sodium(int val){ sodium = val; return this; }public NutritionFacts build() { return new NutritionFacts(this); }

}

private NutritionFacts(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; }

}

CONFIDENTIAL / February 2014 / CEE - CC India

Here’s how the client code looks:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

This client code is easy to write and, more importantly, to read.

Page 25: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

References

• Josh Bloch's Effective Java,• https://developer.android.com/

training/articles/perf-tips.html

Page 26: Android Code Optimization Techniques

RESTRICTED MORPHO

MORPHO RESTRICTEDThis document and the information therein are the property of Morpho, They must not be copied or communicated to a third party without the prior written authorization of Morpho.

Thank you

To be continued