Objective
Code optimization, a very important topic. Some people may feel useless, some small places have what good change, change and do not change the efficiency of the operation of the code has any impact? That's the question I'm thinking about, like a whale in the sea, is it useful to eat a little shrimp? No, but after eating a little shrimp, the whale is fed. Code optimization is also the same, if the project focus on as soon as possible without a bug on-line, then you can grasp the large and small, the details of the code can not be fine grinding; but if there is enough time to develop and maintain the code, you have to consider every detail that can be optimized, a small optimization point accumulates, There is definitely an improvement in the efficiency of the code operation.
The goals of code optimization are:
1, reduce the volume of the Code
2, improve the efficiency of code operation
Code optimization Details
1. Specify the final modifier of the class and method as much as possible
A class with a final modifier is not derived. In the Java Core API, there are many examples of final applications, such as Java.lang.String, where the entire class is final. Specifying the final modifier for a class allows the class not to be inherited, and specifying the final modifier for a method allows the method not to be overridden. If a class is specified as final, all methods of the class are final. The Java compiler will look for opportunities to inline all final methods, and inline is important for improving the efficiency of Java operations, see Java Runtime Optimizations. This will increase the performance by an average of 50%.
2. Reuse objects as much as possible
In particular, the use of String objects should be replaced with stringbuilder/stringbuffer when strings are concatenated. Because Java virtual machines take time not only to generate objects, but may also take time to garbage-collect and process them later, generating too many objects will have a significant impact on the performance of the program.
3. Use local variables whenever possible
Parameters passed when the method is called and temporary variables created in the call are saved in the stack faster, and other variables, such as static variables, instance variables, and so on, are created in the heap and are slower. In addition, the variables created in the stack, as the method runs, are gone, and no additional garbage collection is required.
4. Close the flow in time
In the Java programming process, the database connection, I/O flow operation must be careful, when the use is complete, close in time to release resources. Because the operation of these large objects can cause large overhead, and a slight carelessness, will result in serious consequences.
5, minimize the repetition of the variable calculation
To define a concept, the invocation of a method, even if there is only one sentence in the method, is also consumed, including creating a stack frame, protecting the site when invoking a method, recovering the site when the method is called, and so on. So for example, the following actions:
for (int i = 0; i < list.size(); i++){...}
Suggested substitutions are:
for (int i = 0, int length = list.size(); i < length; i++){...}
In this way, when the list.size () is very large, it reduces a lot of consumption
6, try to use lazy loading strategy, that is, when needed to create
For example:
str = "aaa";if (i == 1){list.add(str);}
Suggested substitutions are:
if (i == 1){String str = "aaa";list.add(str);}
7, cautious use of abnormal
Exceptions are bad for performance. Throws an exception first to create a new object, the constructor of the Throwable interface calls the local synchronization method named Fillinstacktrace (), the Fillinstacktrace () method examines the stack, and collects the call trace information. Whenever an exception is thrown, the Java Virtual machine must adjust the call stack because a new object is created during the process. Exceptions can only be used for error handling and should not be used for control procedures.
8, do not use Try...catch in the loop ..., you should put it on the outermost
Unless there is a last resort. If there is no reason to write this, as long as your leadership senior, obsessive, probably will scold you why write this garbage code
9. If you can estimate the length of the content to be added, specify the initial length for the collection that the underlying array implements, the tool class
such as ArrayList, Linkedllist, StringBuilder, StringBuffer, HashMap, HashSet, and so on, take StringBuilder as an example:
(1) StringBuilder ()//16-character space is assigned by default
(2) StringBuilder (int size)//space with size characters assigned by default
(3) StringBuilder (String str)//default 16 characters +str.length () character space
It is possible to set its initialization capacity through the class (which refers to not just the StringBuilder above), which can significantly improve performance. For example, StringBuilder, length indicates the number of characters the current StringBuilder can hold. Because when the StringBuilder reaches its maximum capacity, it will increase its capacity to the current twice times plus 2, whenever the StringBuilder reaches its maximum capacity, it will have to create a new character array and copy the old character array contents into the new character array-- This is an operation that is very expensive to perform. Imagine, if you can estimate the character array to hold about 5,000 characters without specifying the length, the nearest 5000 of the 2 power is 4096, each expansion plus 2 regardless, then:
(1) on the basis of 4096, and then apply 8,194 size of the character array, add up to the equivalent of a 12,290-size character array, if you can initially specify a 5,000-size character array, saving more than a space
(2) Copy the original 4,096 characters into the new character array.
In this way, both the memory space is wasted and the code runs efficiently. Therefore, it is wrong to set a reasonable initialization capacity for the collection and tool class of the underlying array implementation, which will bring an immediate effect. Note, however, that a collection like HashMap is implemented as an array + linked list, so do not set the initial size to the size you estimate because it is almost 0 more likely to connect an object on a table. The initial size proposal is set to the power of N of 2, which can be set to new HashMap (128), and new HashMap (256) if it can be estimated to have 2000 elements.
10. When copying large amounts of data, use the system.arraycopy () command
11. Multiplication and division using shift operations
For example:
for (val = 0; val < 100000; val += 5){a = val * 8;b = val / 2;}
The shift operation can greatly improve performance, because at the bottom of the computer, the bitwise operation is the most convenient and fastest, so it is recommended to modify:
for (val = 0; val < 100000; val += 5){a = val << 3;b = val >> 1;}
Although the shift operation is fast, it may make the code less understandable, so it's best to add the appropriate comments.
12. Do not constantly create object references within the loop
For example:
for (int i = 1; i <= count; i++){Object obj = new Object();}
This practice causes memory to count as the object reference exists, and if count is large, it consumes memory and is recommended instead:
Object obj = null;for (int i = 0; i <= count; i++) { obj = new Object(); }
In this case, only one copy of the object object is referenced in memory, and each time new object () is used, the object reference points to a different object, but only one copy in memory, which saves memory space considerably.
13, based on the efficiency and type checking considerations, should use as far as possible array, cannot determine the size of the array to use ArrayList
14, try to use HashMap, ArrayList, StringBuilder, unless the thread security needs, it is not recommended to use Hashtable, Vector, StringBuffer, the latter three due to the use of synchronization mechanism resulting in performance costs
15. Do not declare the array as public static final
Because this is meaningless, it simply defines the reference as static final, the contents of the array can be arbitrarily changed, and declaring the array public is a security vulnerability, which means that the array can be changed by the outer class
16, try to use a single case in the appropriate situation
Using a single example can reduce the load burden, shorten the load time, improve the efficiency of loading, but not all places are applicable to a single case, simply speaking, the single case is mainly applicable to the following three aspects:
(1) Control the use of resources, through thread synchronization to control the concurrent access of resources
(2) control of the production of instances to achieve the purpose of saving resources
(3) Controlling the sharing of data, allowing multiple unrelated processes or threads to communicate without establishing a direct association
17, try to avoid arbitrary use of static variables
You know, when an object is referenced by a variable defined as static, the GC usually does not reclaim the heap memory that the object occupies, such as:
public class A{ private static B b = new B();}
At this point, the life cycle of static variable B is the same as Class A, and if Class A is not unloaded, the B object referred to by B will reside in memory until the program terminates
18. Timely removal of sessions that are no longer needed
In order to clear a session that is no longer active, many application servers have a default session timeout, which typically takes 30 minutes. When the application server needs to save more sessions, if there is not enough memory, the operating system will transfer some of the data to disk, and the application server may dump partially inactive sessions to disk based on the MRU (most recently used) algorithm, and may even throw out-of-memory exceptions. If a session is to be dumped to disk, it must be serialized first, and the cost of serializing the object is expensive in a large-scale cluster. Therefore, when the session is no longer needed, the httpsession invalidate () method should be called in time to clear the session.
19, the implementation of the Randomaccess interface, such as ArrayList, should use the most common for loop instead of the Foreach Loop to traverse
This is what the JDK recommends to the user. The JDK API's explanation for the Randomaccess interface is that the implementation of the Randomaccess interface is used to indicate that it supports fast random access, and the primary purpose of this interface is to allow a generic algorithm to change its behavior so that it can provide good performance when applied to random or contiguous access lists. The actual experience shows that the class instance that implements the Randomaccess interface, if it is random access, uses the normal for loop efficiency higher than the Foreach loop, and conversely, if it is accessed sequentially, the use of iterator is more efficient. You can use code like this to make a decision:
if (list instanceof RandomAccess){ for (int i = 0; i < list.size(); i++){}}else{Iterator<?> iterator = list.iterable(); while (iterator.hasNext()){iterator.next()}}
The underlying implementation of the Foreach loop is the iterator iterator, see Java Syntax sugar 1: variable length parameters and the Foreach Loop principle. So the latter half of the sentence "in turn, if it is sequential access, the use of iterator will be more efficient" means that sequential access to those class instances, using the Foreach Loop to traverse.
20. Use synchronous code block instead of synchronization method
This is clearly stated in the synchronized lock method block in multithreaded modules, unless you can determine that a whole method needs to be synchronized, try to use synchronous blocks of code, avoid synchronizing code that does not need to be synchronized, and affect the efficiency of code execution.
21. Declare a constant as static final and name it in uppercase
This allows the content to be placed in a constant pool during compilation, avoiding the value of the generated constant during run time. In addition, it is easy to distinguish constants from variables by naming them in uppercase.
22. Do not create some unused objects, do not import some unused classes
This does not make sense if the code appears "the value of the local variable I am not used", "the import java.util is never used", then remove these useless content
23. Avoid using reflection during program operation
about, see reflection. Reflection is a powerful feature that Java provides to the user, and powerful often means less efficient. It is not recommended to use the Invoke method especially when using the reflection mechanism, especially the method, when the program is running, and if it is necessary, it is suggested that the classes that need to be loaded by reflection will instantiate an object and put it into memory by reflection when the project is started-- The user only cares about the fastest response time when interacting with the peer, and does not care how long it takes to start the project on the end.
24. Using the database connection pool and the thread pool
Both pools are used to reuse objects that avoid frequent opening and closing of connections, which avoids the frequent creation and destruction of threads
25. IO operation with buffered input/output stream
Buffered input and output streams, BufferedReader, BufferedWriter, Bufferedinputstream, Bufferedoutputstream, which can greatly improve IO efficiency
26, sequential insertion and random access more scenes using ArrayList, element deletion and intermediate insertions more scenes using LinkedList
This, understand the principles of ArrayList and LinkedList.
27. Do not let the public method have too many formal parameters
The public method is a method provided externally, and there are two disadvantages to giving these methods too many parameters:
1, violates the object-oriented programming idea, Java stresses that everything is object, too many formal parameters, and object-oriented programming thinking does not fit
2, too many parameters will inevitably lead to the error probability of the method call increased
As for this "too much" refers to how many, 3, 4 bar. For example, we use JDBC to write a insertstudentinfo method, there are 10 student information fields to be inserted into the student table, you can encapsulate these 10 parameters in an entity class, as the parameter of the Insert method
28, string variable and string constant equals when the string constant is written in front
This is a relatively common little trick, if you have the following code:
"123";if (str.equals("123")) {...}
Suggested changes to:
"123";if ("123".equals(str)){...}
This is done primarily to avoid null pointer exceptions
29, please know, in Java if (i = = 1) and if (1 = = i) is no difference, but from the reading habit, the use of the former is recommended
At ordinary times someone asked, "if (i = = 1)" and "if (1== i)" There is no difference, this will start from C + +.
The "if (i = = 1)" Criterion is determined by 0 and non-0, 0 for false, and not 0 for true if there is such a piece of code:
2;if (i == 1){...}else{...}
C + + judgment "I==1″ not set, so 0, that is, false." But if:
2;if (i = 1) { ... }else{ ... }
In case the programmer is careless, write "if (i = = 1)" As "if (i = 1)", so there is a problem. If I is assigned to 1,if within if the content is not 0, the return is true, but clearly I is 2, the value of the comparison is 1, should return false. This situation is most likely to occur in the development of C/s + + and can cause some incomprehensible errors, so in order to avoid the developer's incorrect assignment in the IF statement, it is recommended that the IF statement be written as:
2;if (1 == i) { ... }else{ ... }
In this way, even if the developer accidentally wrote "1 = i", the C + + compiler can check out the first time, because we can assign a variable to the value I is 1, but cannot assign a value of 1 to a constant.
However, in Java, the syntax for this "if (i = 1)" is not possible, because once this syntax is written, Java compiles an error "Type mismatch:cannot convert from int to Boolean". However, although Java's "if (i = = 1)" and "if (1 = = i)" Have no semantic differences, it is better to use the former in terms of reading habits.
30. Do not use the ToString () method on an array
Look at what the array is printed with ToString ():
public static void main(String[] args){ int[] is = new int[]{1, 2, 3};System.out.println(is.toString());}
The result is:
[I@18a992f
It is intended to print an array of contents, but it is possible that the null pointer exception is due to the fact that the arrays reference is null. However, although the array ToString () does not make sense, the set ToString () is able to print out the contents of the collection, because the parent of the collection Abstractcollections overrides the ToString () method of object.
31. Do not make a downward transition to the underlying data type that is out of range
This will never get the result you want:
public static void main(String[] args){ long l = 12345678901234L;int i = (int)l;System.out.println(i);}
We may expect to get some of them, but the result is:
1942892530
Explain. In Java, Long is 8 bytes in 64 bits, so the 12345678901234 representation in a computer should be:
0000 0000 0000 0000 0000 1011 0011 1010 0111 0011 1100 1110 0010 1111 1111 0010
An int data is 4 bytes 32 bits, and the first 32 bits of this binary data are removed from the low:
0111 0011 1100 1110 0010 1111 1111 0010
This string binary is represented as a decimal 1942892530, so it is the output on the console above us. From this example, you can also get two conclusions:
1, the integer default data type is Int,long L = 12345678901234L, this number has exceeded the range of int, so finally there is an L, indicating that this is a long type number. By the way, the default type of float is double, so when you define float you write "" Float f = 3.5f "
2. Then write another sentence, "int II = L + i;" Error, because long + int is a long and cannot be assigned to int
32, the Common collection class does not use the data must be removed in time
If a collection class is public (that is, it is not a property within the method), the elements inside the collection are not automatically freed because references are always directed to them. Therefore, if some of the data in a common collection is not used without going to remove them, it will cause this common set to grow, causing the system to have a hidden memory leak.
33. To convert a basic data type to a string, the base data type. ToString () is the quickest way, string.valueof (data), Data + "" slowest
To convert a basic data type to a general three ways, I have an integer data I, can use i.ToString (), string.valueof (i), i+ "" Three ways, three ways of efficiency, see a test:
PublicStaticvoidMain (string[] args) {int looptime =50000;integer i =0;Long startTime = System.currenttimemillis ();for (Int J =0; J < Looptime; J + +) {String str = string.valueof (i);} System.out.println ( "string.valueof ():" + (System.currenttimemillis ()-StartTime) + "MS"); startTime = System.currenttimemillis (); for (int j = 0; j < LoopTime; J + +) { String str = i.tostring ();} System. out.println ( "integer.tostring ():" + ( System.currenttimemillis ()-startTime) + "MS"); startTime = System.currenttimemillis (); for (int j = 0; j < LoopTime; J + +) { String str = i + out.println ( "i + \" \ ":" + (System.currenttimemillis ()- StartTime) + "MS");}
The result of the operation is:
String.valueOf():11ms Integer.toString():5ms i + "":25ms
Therefore, the ToString () method is preferred when you encounter a conversion of a basic data type into string. As for why, it's simple:
1. The string.valueof () method calls the Integer.tostring () method at the bottom, but it will be bearish before the call
2, Integer.tostring () method will not say, directly called the
3, i + "" bottom using StringBuilder implementation, first with the Append method splicing, and then use the ToString () method to get the string
In contrast, the three are clearly 2 fastest, 1 times, 3 slowest
34. Use the most efficient way to traverse the map
There are many ways to traverse a map, and the most common scenario we need is to traverse the key and value in the map, so the most efficient way to use it is:
public static void Main (String[] args) {hashmap<string, string> HM = new Hashmap<string, string> (); Hm.put ( "111", "222"; set<map.entry<string, string>> EntrySet = Hm.entryset (); Iterator<map.entry<String, string>> iter = Entryset.iterator (); while (Iter.hasnext ()) {Map.entry<String, string> entry = iter. next (); System.out.println (Entry.getkey () + "\ T" + entry.getvalue ());}}
If you just want to traverse the key value of this map, use "Set KeySet = Hm.keyset ();" would be more appropriate.
35, the close () to the resources proposed separate operation
It means, for example, that I have this piece of code:
try{XXX.close();YYY.close();}catch (Exception e){...}
Suggested changes to:
try{ XXX.close(); }catch (Exception e) { ... }try{ YYY.close(); }catch (Exception e) { ... }
Although there is some trouble, it can avoid resource leakage. We think, if there is no modified code, in case Xxx.close () throws an exception, then into the Cath block, Yyy.close () will not execute, YYY this resource will not be recycled, has been occupied, such a lot of code, is likely to cause the disclosure of resource handle. And instead of the following wording, it is guaranteed that XXX and yyy will be close off anyway.
Welcome to Java Learning Group: 669823128
Summary of 35 Java code performance optimizations