Android performance optimization and Android Application Performance Optimization

Source: Internet
Author: User

Android performance optimization and Android Application Performance Optimization
Google Performance

Http://developer.android.com/intl/zh-cn/training/articles/perf-tips.html

This article mainly involves some minor optimizations. Combined use can improve the overall performance of the App, but does not significantly improve the performance. An appropriate algorithm and data structure are preferred for improving performance, which is beyond the scope of this article. The skills here should serve as your usual habit of writing code to write efficient code.

Efficient code has two basic rules:

  • Do not do unnecessary things
  • Try not to allocate memory

When optimizing the Android program, you need to face different hardware, different versions of VMS, different processors, and different speeds! Testing on Simulators rarely involves performance. Whether JIT is available has a great impact.

Avoid creating unnecessary objects

Object creation is not free. Garbage collection also requires costs.

If the method returns a String, the result will always be added to the StringBuffer. You should modify the function to implement the signature without creating a temporary object and appending it directly.
When extracting strings from a group of input data, return substring instead of creating a copy. in this way, although a new String object is created, it shares char [] with the input data (if only a small part of the source data is used, the entire data cannot be recycled .).

Some more radical practices are to cut multi-dimensional arrays into multiple one-dimensional arrays: int [] is more efficient than Integer.

Use Static instead of Virtual

If you do not need to access the object members, declare the method as static, and the call speed will be increased by 15%-20%. This is a good habit, because we can identify from the method signature that this method call will not affect the object state.

Use Static Final to define Constants
static int intVal = 42;static String strVal = "Hello, world!";

 

The compiler generates a class initialization method <clinit> called when the class is used for the first time. This method saves 42 to intVal and assigns the reference to strVal from the String constant table of the class file. When these values are used later, field lookup is used.

Add final:

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

 

This class no longer requires a <clinit> method, because constants will enter the static field initializers of the dex file ). When intVal is referenced, it is replaced by 42 directly.

Note: This optimization only applies to the basic and String types, rather than any reference types. But it is still a good habit to add the static final prefix when declaring constants.

Avoid internal Getters/Setters

In C ++ and other native languages, getters (I = getCount () is often used to replace Member access (I = mCount). In this way, the compiler can inline access and control access permissions. However, access to virtual Methods on Android is more expensive than field lookup.

Access by members without JIT is about three times faster than access by getter. Using JIT to access member variables is as cheap as accessing local variables. member access is about seven times faster than getter access.

Note that ProGuard can Inline code.

Use enhanced edition For Loop

Enhanced For loop (also called "for-each" loop) can be used to enumerate the set and array that implement the Iterable interface. The Set assignment iterator (iterator) object to implement the hasNext () and next () methods. The loop with counters written by ArrayList is three times faster, while the efficiency of other sets is similar.

Below are several common iterative array scenarios:

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;    }}

 

Zero () is the slowest, because JIT cannot optimize the overhead of getting the array length during each loop.
One () is faster. It copies all required items in local variables to avoid searching. However, only the optimization of the array length produces results.
Two () is the fastest on devices without JIT, but it is no different from one () On devices with JIT. It uses a forced version of The for loop.

 

Use package-level access instead of private access of internal classes

For the following code

public class Foo {    private class Inner {        void stuff() {            Foo.this.doStuff(Foo.this.mValue);        }    }    private int mValue;    public void run() {        Inner in = new Inner();        mValue = 27;        in.stuff();    }    private void doStuff(int value) {        System.out.println("Value is " + value);    }}

 

This class defines an internal class (Foo $ Inner) and directly accesses the private methods and Private Members of the outer class. For virtual machines, access to the Foo private method by Foo $ Inner is illegal because they are different classes, but the Java syntax allows such access, therefore, the virtual opportunity generates a dynamic method to solve this problem.

/*package*/ static int Foo.access$100(Foo foo) {    return foo.mValue;}/*package*/ static void Foo.access$200(Foo foo, int value) {    foo.doStuff(value);}

 

Each time Foo $ Inner accesses the private member or private method of Foo, it is directly called, but it is actually accessed through these static access methods, method calls are much slower than Member calls. When defining member variables, it is best to change them to public or default, but this will expose the class members, so do not do this in public APIs.


Avoid floating point number

Float on Android devices is twice slower than int devices.

There is no difference in the speed of float and double types on current hardware devices, but the latter occupies two times of space. It is not a problem for desktop space, but Android is a problem.

In addition, some machines with integer data have hardware multiplication, but there is no division. Division or remainder operations are implemented by software. If you design a hash table or perform many mathematical operations, consider these operations.

 

Use library functions

The Code provided in the library is given priority. Sometimes the system can replace the library method with the assembly code (hand-coded handler), which is more efficient than JIT, such as String. indexOf () and related APIs, Dalvik uses inline implementation. Similarly, System. arraycopy () is 9 times faster than a handwritten loop on a nexus device with JIT.

 

Use native functions with caution

Native code based on NDK may not be faster than Java, because the conversion before java-native also requires cost, and JIT cannot optimize this boundary. If you use local resources (native-resources, memory, files, or other resources), timely resource recovery will become more difficult. You also need to compile the local code into various racks. NDK is generally used to migrate the original code to the Android platform, not to "accelerate" Java.

If native code is required, check JNI Tips.

Misunderstandings about performance

On devices without JIT, calling methods by specific types is faster than calling methods by using interfaces (for example, calling HashMap map is faster than Map, although they actually call HashMap methods ). Previously it was said that it would be about twice slower, but in fact it was about 6% slower, and there was almost no difference on JIT devices.

In equipment vendors without JIT, access to cache members is about 20% faster than repeated access, but for JIT, access to members is almost the same as local variables, so this optimization is not very significant, unless this makes your code more readable. (Also applicable to variables modified with static, final, and static final)

 

Continuous Measurement

Before you begin optimization, make sure that you have performance problems to solve and ensure that the current performance is accurately measured. Otherwise, you cannot figure out the performance improvements brought about by optimization.

These standard tests are based on the Java version of the Caliper microtest (Microbenchmarks) framework. Microbenchmarks is hard to be accurate, so Caliper helped us with this, and even detected some situations where we thought the test was done but not tested (because the VM optimized the Code ). It is strongly recommended that you use Caliper to run your own micro-test program.

It is also useful to use Traceview. Remember that currently Traceview does not start JIT, so it misestimates the time optimization brought by JIT. After the Traceview data is changed, the actual code can run faster without Traceview.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.