Write an efficient Android code

Source: Internet
Author: User
Tags iterable mathematical functions

write an efficient Android code

There is no doubt that Android-based devices must be embedded devices. Modern handheld devices are more than just a phone, it is a small handheld computer, but even the fastest top-end handheld device is far less than a medium-performance desktop.
This is why you should always consider the efficiency of execution when writing an Android program, which is not as fast as you think, and you have to consider the battery's endurance. This means that there is not much space left for you to waste, so when you write your Android program, you need to optimize your code as much as possible to improve efficiency.
This page describes several ways to make the developer's Android program run more efficiently. You can learn how to make your program run more efficiently by following some of the jump connections.


Introduction

Here are two basic principles for how to judge a system's irrational:
Don't do what you don't have to do.
Save as much memory as possible.
All of the following methods are based on these two items.
Some would argue that this page has taken a lot of space to talk about "preliminary optimization" (premature optimization). While micro-optimization is sometimes difficult to develop efficient data structures and algorithms, you have no choice on embedded handheld devices. For example, if you are porting a desktop computer's virtual machine to your Android system, you will find that the program you write will run out of memory. This causes the program to run extremely slowly, even if it does not consider the impact it has on other running programs on the system.
That's why the above two principles are so important. The success of Android lies in the experience that the development program provides to the user, but the quality of the user experience depends on whether your code responds in a timely manner and does not cause a slow crash. Because all of our programs run on the same device, we consider them as a whole. This article is like the traffic rules you need to study for your driving license: If everyone follows, things will be smooth, but when you don't, you'll crash.
Before we discuss the substantive issues, there is a brief explanation: Regardless of whether the virtual machine is a feature of the Java compiler, all the ideas presented below are correct. If we have two ways to do the same thing, but Foo () 's interpretation is faster than bar (), then Foo () must compile faster than bar (), and it's unwise to rely solely on the compiler to make your code run faster.

Avoid creating objects (object) whenever possible

The creation of an object is not without cost. A generational memory management mechanism with a thread allocation pool reduces the cost of creating temporary objects, rather than allocating memory better than not allocating memory.
If you allocate an object in the loop of a user interface, you have to force a memory recycle, which can make the user experience a little "hiccup".
Therefore, you should not create an object instance if it is not necessary. Here's a helpful example:
When extracting a string from the original input data, try to return a substring from the original string instead of creating one copy. You will create a new string object, but it shares the data space with your original data.
If you have a method that returns a string, you should know that the result returned anyway is stringbuffer, changing the definition and execution of your function so that the function returns directly instead of creating a temporary object.
A more radical approach is to split a multidimensional array into several parallel one-dimensional arrays:
An array of type int is better than an array of type integer, but it can also be summed up in such a principle that an array of two int types is much more efficient than an array of (Int,int) objects. For other raw data types, the same principle applies.
? If you need to create a container (container) that contains a series of Foo and Bar objects, remember that two parallel foo[] and bar[] are much more efficient than an array of (Foo,bar) objects. (There is an exception to this example, when you design interface APIs for other code, in which case a little loss of speed is not considered.) However, in your code, you should write efficient code as much as possible. )
In general, avoid creating short-term temporary objects as much as possible. Fewer object creation means less garbage collection, which improves the quality of your program's user experience.

using its own method (use Native Methods)

When dealing with strings, do not hesitate to use as many of the methods of the object as possible, such as String.IndexOf (), String.LastIndexOf (). Because these methods are implemented by using C + +, it is 10-100 times faster than doing the same thing in a Java loop.
One more thing to add is that the cost of using these methods is much higher than the ones explained, and therefore, for subtle operations, try not to use such methods.

using virtual better than using interfaces

Suppose you have a HashMap object, you can declare it to be a hashmap or just a map:

Java code
    1. Map myMap1 = new HashMap ();
    2. HashMap myMap2 = new HashMap ();


Which one is better?
It is generally wise to use map because it allows you to change the map interface to perform anything above, but this "sensible" approach is only appropriate for regular programming and not for embedded systems. Calling through an interface reference can take more than twice times longer than a call to a virtual function through a specific reference.
If you choose to use a hashmap because it is more appropriate for your programming, then using a map is worthless. Assuming you have an integrated coding environment that can refactor your code, it is not useful to call a map, even if you are not sure where your program starts. (Again, the public API is an exception, the value of a good API is often greater than the loss of execution efficiency)

using static better than using virtual

If you don't have to go to the outside of the object, make your method a static method. It will be called faster because it does not require a virtual function-oriented table. This is also a good practice, because it tells you how to differentiate the nature of the method (signature), and calling this method does not change the state of the object.

avoid using intrinsic get, set methods as much as possible

Like the C++iyangde programming language, a Get method (such as I = GetCount ()) is typically used instead of direct access to this property (I=mcount). This is a good practice in C + + programming, because the compiler will set the access mode to inline, and if you want to constrain or debug property access, you just need to add some code at any time.
In Android programming, this is not a very bad idea. Calls to virtual methods incur many costs, more than instance property queries. We should use the get and set functions when calling externally, but we should call them directly when we call them internally.

Buffered Properties Call cache Field Lookups

Accessing object properties is much slower than accessing local variables. You should not write your code like this:

Java code
    1. for (int i = 0; i < This.mcount; i++)
    2. Dumpitem (This.mitems[i]);


But it should be written like this:

Java code
    1. int count = This.mcount;
    2. item[] items = this.mitems;
    3. for (int i = 0; i < count; i++)
    4. Dumpitems (Items[i]);


(We directly use "this" to indicate that these are its member variables)
A similar principle is to never call a method of a class for the second time in a for statement. For example, the following code will execute the GetCount () method over and over again, which is a huge waste compared to when you hide it directly into an int variable.

Java code
    1. for (int i = 0; i < This.getcount (); i++)
    2. Dumpitems (This.getitem (i));


This is a better approach when you call an instance more than once, localize the instance directly, and assign some of the values in this instance to a local variable. For example:

Java code
  1. protected void Drawhorizontalscrollbar (canvas canvas, int width, int height) {
  2. if (ishorizontalscrollbarenabled ()) {
  3. int size = Mscrollbar.getsize (false);
  4. if (size <= 0) {
  5. size = Mscrollbarsize;
  6. }
  7. Mscrollbar.setbounds (0, height-size, width, height);
  8. Mscrollbar.setparams (
  9. Computehorizontalscrollrange (),
  10. Computehorizontalscrolloffset (),
  11. Computehorizontalscrollextent (), false);
  12. Mscrollbar.draw (canvas);
  13. }
  14. }


There are four Mscrollbar property calls, and Mscrollbar is buffered into a stack variable, and the call to the four-member property becomes the four-time access to the stack, which increases efficiency.
Incidentally, a method can also have the same characteristics as a local variable.

declaring final constants

We can take a look at the declaration at the top of the following class:

Java code
    1. static int intval = 42;
    2. static String Strval = "Hello, world!";


When a class is first used, the compiler invokes a class initialization method--<clinit>, which stores 42 in the variable intval and extracts a reference for Strval in the class file string constant table, which is called directly when the values are referenced later.
We can use the keyword "final" to improve the code:

Java code
    1. static final int intval = 42;
    2. Static final String Strval = "Hello, world!";


This class will not invoke the ES a <clinit> method because these constants are directly written to the class file static property initialization, which is handled directly by the virtual machine. Code access Intval will use an integer type of 42, and access Strval will replace a property call with a relatively saved "string constant".
Declaring a class or method as "final" does not result in any benefit of execution, it can be handled with some optimization. For example, if the compiler knows that a get method cannot be overridden by a class, it sets the function to inline.
Also, you can declare a local variable as a final variable. But that doesn't make any sense. As a local variable, using final can only make the code clearer (or you have to use it when you have anonymous access to the inline class).

use enhanced for loop statements with caution

The enhanced for loop (also known as the "For-each loop") is often used on the inheritance collection interface of the Iterable interface. Within these objects, a iterator is assigned to the object to invoke its Hasnext () and Next () methods. In an array list, you can pick it up yourself, and in other collectors, the enhanced for loop will be equivalent to iterator's use.
Nonetheless, the following source code gives an example of an acceptable enhanced for loop:

Java code
  1. public class Foo {
  2. int Msplat;
  3. Static Foo marray[] = new FOO[27];
  4. public static void Zero () {
  5. int sum = 0;
  6. for (int i = 0; i < marray.length; i++) {
  7. sum + = Marray[i].msplat;
  8. }
  9. }
  10. public static void One () {
  11. int sum = 0;
  12. foo[] LocalArray = Marray;
  13. int len = localarray.length;
  14. for (int i = 0; i < len; i++) {
  15. sum + = Localarray[i].msplat;
  16. }
  17. }
  18. public static void () {
  19. int sum = 0;
  20. for (Foo A:marray) {
  21. sum + = A.msplat;
  22. }
  23. }
  24. }


The zero () function re-obtains the static property two times in each loop, obtaining the array length once.
The one () function changes everything to a local variable, avoiding the class lookup property call
The second () function uses the FOR Loop statement in version 1.5 of the Java language, and the source code generated by the editor takes into account the reference of the copy array and the length of the arrays to local variables, which is a good way to sample the array, and it does produce an additional loading and storage process in the main loop (apparently preserving "a"). It has a bit slower and 4-byte growth compared to function one ().
After summing up, we can get: the enhanced for loop behaves well in the array, but be cautious when working with iterable objects, because there is more than one object created.

avoid enumerating types avoid Enums

The enumeration type is very useful, when considering the size and speed, it will be very expensive, for example:

Java code
    1. public class Foo {
    2. Public enum Shrubbery {GROUND, crawling, hanging}
    3. }


This translates into a 900-byte class file (Foo$shrubbery.class). For the first time, the initialization of the class is to invoke the method to describe each of the enumerated items, and each object has its own static space, which is stored in an array (a static array called "$VALUE"). That's a lot of code and data, just for three integer values.

Java code
    1. Shrubbery shrub = shrubbery.ground;


This causes a call to a static property, and if ground is a static final variable, the compiler will nest it as a constant in the code.
One more thing to say, by enumerating, you can get better APIs and some compile time checks. Therefore, a more balanced approach is that you should do everything in your public API to use enumerated variables, as much as possible when dealing with problems.
Under some circumstances, it is useful to get an integer value of an enumeration variable by using the ordinal () method, for example: put the following code

Java code
    1. for (int n = 0; n < list.size (); n++) {
    2. if (list.items[n].e = = myenum.val_x)
    3. Do stuff 1
    4. else if (list.items[n].e = = myenum.val_y)
    5. Do stuff 2
    6. }


To be replaced by:

Java code
  1. int valx = MyEnum.VAL_X.ordinal ();
  2. int valy = MyEnum.VAL_Y.ordinal ();
  3. int count = List.size ();
  4. MyItem items = List.items ();
  5. for (int n = 0; n < count; n++)
  6. {
  7. int valitem = Items[n].e.ordinal ();
  8. if (Valitem = = valx)
  9. Do stuff 1
  10. else if (Valitem = = valy)
  11. Do stuff 2
  12. }


Under some conditions, this will execute faster, although there is no guarantee.

using package space through inline classes

Let's look at the following class declaration

Java code
  1. public class Foo {
  2. private int mvalue;
  3. public void Run () {
  4. Inner in = new Inner ();
  5. Mvalue = 27;
  6. In.stuff ();
  7. }
  8. private void Dostuff (int value) {
  9. System.out.println ("value is" + value);
  10. }
  11. Private class Inner {
  12. void Stuff () {
  13. Foo.this.doStuff (Foo.this.mValue);
  14. }
  15. }
  16. }


What we should note here is that we define an inline class that invokes the private methods and private properties of the outer class. This is a legitimate call and the code should display "Value is 27".
The problem is that Foo$inner in theory (running in the background) is supposed to be a completely separate class that calls the private members of Foo illegally. To compensate for this flaw, the compiler produces a pair of synthetic methods:

Java code
    1. /*package*/static int foo.access$100 (foo foo) {
    2. return foo.mvalue;
    3. }
    4. /*package*/static void foo.access$200 (foo foo, int value) {
    5. Foo.dostuff (value);
    6. }


Inline classes invoke these static methods when the inline class needs to access "Mvalue" from outside and call "Dostuff", which means that you are not accessing the class members directly, but by public means. Before we talked about indirect access is slower than direct access, so this is an example of invisible execution by language habits.
By letting inline classes that have a package space directly declare the properties and methods that need to be accessed, we can avoid the problem that philosophical poetry is a package space rather than a private space. This runs faster and removes the build function in front of the thing. (Unfortunately, it also means that the property can be accessed directly from other classes under the same package, which violates the standard object-oriented principle of making all properties private.) Similarly, if you are designing a public API, you should carefully consider the use of this optimization.

avoiding the use of floating-point types

Before the Pentium CPU was released, it was normal for game authors to use the integer type of mathematical functions as much as possible. In the Pentium processor, the processing of floating-point numbers becomes a prominent feature, and the use of floating-point numbers and integers compared to the use of integers alone, the former will make your game run faster, generally on the desktop computer we can freely use floating point.
Unfortunately, embedded processors do not usually support floating-point processing, and all the "float" and "double" operations of the labia are software-based, and some basic floating-point operations take a millisecond of time.
Colleagues, even integers, some chips have only multiplication and no division. In these cases, the Division and modulo operations of integers are implemented by software. When you create a hash table or do a lot of math, that's all you have to think about.

time comparison of some standard operations

To illustrate our point of view, here is a list of the approximate times used by some basic operations. Note that these times are not absolute times, and the absolute time takes into account the CPU and clock frequency. The size of the time varies depending on the system. Of course, this is also a meaningful comparison, and we can compare it to the relative time spent on different operations. For example, adding a member variable is four times times the time of adding a local variable.

Action Time
ADD a local variable 1
ADD a member variable 4
Call String.Length () 5
Call empty static native method 5
Call Empty static method 12
Call Empty virtual method 12.5
Call Empty interface method 15
Call Iterator:next () on a HashMap 165
Call put () on a HashMap 600
Inflate 1 View from XML 22,000
Inflate 1 linearlayout containing 1 TextView 25,000
Inflate 1 LinearLayout containing 6 View objects 100,000
Inflate 1 LinearLayout containing 6 TextView objects 135,000
Launch an empty activity 3,000,000



Concluding remarks

The best way to write an efficient embedded program is to figure out what the program you're writing is doing. If you really want to assign a iterator class, go into all the ways to use the enhanced for loop in a list to make it a deliberate, rather than an inadvertent omission that has a negative impact.
Be prepared and figure out what you're doing! You can assume some of your own code of conduct, but be sure to pay attention to what you're doing and then start looking for ways to optimize it.

Write an efficient Android code

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.