How to write efficient Android code

Source: Internet
Author: User
Tags arrays constant garbage collection int size stringbuffer

Based on the Android-related devices as embedded devices, we should pay more attention to the efficiency when writing app application, and be limited by the battery charge. This leads to a number of considerations and limited processing capabilities for embedded devices, so it requires us to write efficient code as much as possible. This article discusses many ways for developers to make their programs run more efficiently, and by following these methods, you can make your program work the most effective.

Introduction


there are two basic principles for resource-consuming systems:


don't do anything unnecessary


do not allocate unnecessary memory


all of the following are in accordance with these two principles.


1, avoid establishing objects


There is no free object in the world. Although GC creates a temporary object pool for each thread, the cost of creating objects becomes smaller, but allocating memory is never more costly than allocating memory.


If you allocate object memory in the user interface loop, you can trigger periodic garbage collection, and users will feel the interface is like a hiccup.


so, unless necessary, try to avoid examples of objects. The following example will help you understand this principle:


when you intercept a string from a user's input, try to use the SUBSTRING function to get a substring of the original data instead of creating a separate copy for the substring. So you have a new string object that shares a char array with the original data.


If you have a function that returns a string object and you know exactly that the string will be appended to a stringbuffer, change the parameter and implementation of the function and attach the result directly to the StringBuffer. Instead of creating a short-lived temporary object.


A more extreme example is the partitioning of multidimensional arrays into multiple one-dimensional arrays:


An int array is better than an integer array, which also sums up a basic fact that two parallel arrays of int are much better than the (Int,int) object array performance. In the same vein, this test is used for all basic types of combinations.


If you want to use a container storage (foo,bar) tuple, try using two separate foo[] arrays and bar[arrays, which are more efficient than (foo,bar) arrays. (There are exceptions, too, when you create an API to let someone call it.) At this point you have to pay attention to the design of API excuses and sacrifice a bit of speed. Of course, within the API, you still have to be as efficient as possible in the code.


, in general, is to avoid creating short-lived temporary objects. Reducing the creation of objects reduces garbage collection and thus reduces the impact on the user experience.


2, using local method


when you are dealing with strings, do not begrudge the use of String.IndexOf (), String.LastIndexOf () and other special implementation methods. These methods are implemented using C/s + +, 10 to 100 times times faster than Java loops.


but also not to use local methods entirely, the cost of invoking a local method is higher than invoking the interpretation method. So if you can avoid it, you should not use a local method to do something that is not complex.


3, select Virtual class instead of interface


Suppose you have a HashMap object that you can declare as HashMap or map:


Map myMap1 = new HashMap ();


HashMap myMap2 = new HashMap (); Which is better?


The traditional view map is better, because you can change his implementation class as long as the class inherits from the map interface. Traditional views are correct for traditional programs, but they are not suitable for embedded systems. Invoking a reference to an interface can take one more time than a reference to a call to an entity class. If HashMap is perfect for your program, then using map is of little value. If you are unsure of some places, avoid using the map, and the rest of the refactoring provided by the IDE is good. (Of course the public API is an exception: a good API often sacrifices some performance)


4, using static method is better than virtual method


If you do not need to access the member variables of an object, then declare the method static. A virtual method executes faster because it can be called directly without requiring a table of virtual functions. Alternatively, you can declare that the invocation of this function does not change the state of the object.


5, without getter and setter


in many native languages such as C + +, getter (for example, i = GetCount ()) is used to avoid direct access to member variables (i = mcount). This is a very good habit in C + + because the compiler can inline access, and if you need to constrain or debug variables, you can add code at any time. On Android, that's not a good idea. A virtual method is much more expensive than a direct access member variable. In a generic interface definition, getters and setters can be defined in OO terms, but in a generic class, you should directly access variables.


6, caching member variables to local


accessing a member variable is much slower than accessing a local variable, the following code:


for (int i = 0; i < this.mcount i++) Dumpitem (this.mitems[i]); You should write: int count = This.mcount;   item[] items = this.mitems; for (int i = 0; i < count; i++) Dumpitems (Items[i]); (The display uses "This" to indicate that these are member variables)


Another similar principle is: Never call any method in the second condition of for. As shown in the following method, the GetCount () method is invoked at each loop, which is much more expensive than saving the results in an int first.


for (int i = 0; i < This.getcount (); i++)


Dumpitems (This.getitem (i)); If you want to access a variable multiple times, it's also a good idea to create a local variable for it, for example:


protected void Drawhorizontalscrollbar (Canvas Canvas, int width, int height) {if (ishorizontalscrollbarenable   D ()) {int size = Mscrollbar.getsize (false);   if (size <= 0) {size = Mscrollbarsize;   Mscrollbar.setbounds (0, height–size, width, height);   Mscrollbar.setparams (Computehorizontalscrollrange (), Computehorizontalscrolloffset (),   Computehorizontalscrollextent (), false);   Mscrollbar.draw (canvas); }   }


There are 4 accesses to the member variable Mscrollbar, and if you cache it locally, 4 member variable accesses will become 4 more efficient stack variable accesses.


by the way, the parameter of the method is the same as the performance of the local variable.


7, using constant


Let's take a look at these two paragraphs in front of the class statement:


static int intval = 42;


static String Strval = "Hello, world!";

The
compiler generates a method called the <clinit> initialization class, which is executed when the class is used for the first time. Method assigns 42 to Intval, and then assigns a reference to the constant table in the class to Strval. When these values are to be used later, they are found in the table of member variables.


we can make some improvements, using the "final" keyword:


static final int intval = 42;


static final String strval = "Hello, world!";


now, the class no longer needs the <clinit> method, because constants are saved directly to the class file when the member variable is initialized. Code that uses intval is replaced directly with 42, while using strval points to a string constant instead of using a member variable.


declaring a method or class as "final" does not improve performance, but it helps the compiler optimize the code. For example, if the compiler knew that an "getter" method would not be overloaded, the compiler would invoke it inline.


You can also declare a local variable to be final, which in turn does not lead to a performance boost.      Using final only makes local variables look clearer (but sometimes this is necessary, for example, when using anonymous inner classes). Concluding remarks:


the best way to write the right and efficient code for an embedded system is to understand what your code is going to do. If you really want to allocate an iterator or use the enhanced looping syntax on lists anyway, then it must be a deliberate choice, not a side effect of a careless heart. All things are in advance, not in advance. Be sure to know what you are doing. Write code in your own style, but be sure to think carefully about what the code does and find a way to speed it up.
Related Article

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.