Performance optimization summary of 35 java development codes
Foreword
Code optimization is a very important topic. Some people may think it's useless. What can be changed in some small places? What is the impact of changing or not on the running efficiency of the code? I think about this question like a whale in the sea. Is it useful for it to eat a small shrimp? It's no use, but after eating more shrimps, the whales are fed. The same is true for code optimization. If the project focuses on going online without bugs as soon as possible, we can focus on the big and let go of the small at this time, and the details of the code can not be refined; However, if you have enough time to develop and maintain the code, you must consider every detail that can be optimized. The accumulation of small optimization points will definitely improve the operation efficiency of the code.
The objectives of code optimization are:
1. Reduce the size of the code
2. Improve the efficiency of code operation
Code optimization details
1. Try to specify the final modifier of classes and methods
Classes with the final modifier are not derivable. In the Java core API, there are many examples of applying final, such as Java Lang. string, the whole class is final. Specifying a final modifier for a class prevents the class from being inherited, and specifying a final modifier for a method prevents the method from being overridden. If a class is specified as final, all methods of that class are final. The java compiler will look for opportunities to inline all final methods. Inline plays an important role in improving Java running efficiency. See Java runtime optimization for details. This can improve performance by an average of 50%.
2. Reuse objects as much as possible
Especially for the use of string objects, StringBuilder / StringBuffer should be used instead of string connection. Because the Java virtual machine not only takes time to generate objects, but also takes time to garbage collect and process these objects in the future, generating too many objects will have a great impact on the performance of the program.
3. Use local variables as much as possible
The parameters passed when calling the method and the temporary variables created in the call are saved in the stack, which is faster. Other variables, such as static variables and instance variables, are created in the heap, which is slower. In addition, the variables created in the stack will disappear as the method runs, and no additional garbage collection is required.
4. Close the flow in time
In the process of Java programming, be careful in database connection and I / O flow operation. After use, close it in time to release resources. Because the operation of these large objects will cause large system overhead, a little carelessness will lead to serious consequences.
5. Minimize repeated calculation of variables
A clear concept is that calling a method, even if there is only one sentence in the method, will consume, including creating a stack frame, protecting the site when calling the method, restoring the site when calling the method, etc. So, for example, the following operations:
for (int i = 0; i < list.size(); i++) {...}
It is suggested to replace with:
for (int i = 0, int length = list.size(); i < length; i++) {...}
So, in the list When size () is very large, it reduces a lot of consumption
6. Try to use the lazy loading strategy, that is, create it when necessary
For example:
String str = "aaa";if (i == 1) { list.add(str); }
It is suggested to replace with:
if (i == 1) { String str = "aaa"; list.add(str); }
7. Use with caution
Exceptions are detrimental to performance. To throw an exception, first create a new object. The constructor of the throwable interface calls the local synchronization method named fillinstacktrace(). The fillinstacktrace() method checks the stack and collects call trace information. Whenever an exception is thrown, the Java virtual machine must adjust the call stack because a new object is created during processing. Exceptions can only be used for error handling and should not be used to control program flow.
8. Do not use try & hellip in the loop; catch…, It should be placed on the outermost layer
Unless you have to. If you write this for no reason, as long as your leader is more senior and obsessive-compulsive, eight achievements will scold you for writing this kind of junk code
9. If the length of the content to be added can be estimated, specify the initial length for the underlying collections and tool classes implemented in array
For example, ArrayList, linkedllist, StringBuilder, StringBuffer, HashMap, HashSet, etc. take StringBuilder as an example:
(1) stringbuilder() / / 16 character space is allocated by default
(2) StringBuilder (int size) / / a space of size characters is allocated by default
(3) StringBuilder (string STR) / / 16 characters + str.length () character spaces are allocated by default
You can use class (this refers not only to the above StringBuilder) to set its initialization capacity, which can significantly improve the performance. For example, StringBuilder, length indicates the number of characters that the current StringBuilder can maintain. Because when the StringBuilder reaches the maximum capacity, it will increase its capacity to twice the current capacity plus 2, whenever the StringBuilder reaches the maximum capacity At its maximum capacity, it has to create a new character array, and then copy the contents of the old character array to the new character array & mdash- This is a very performance intensive operation. Imagine that if it can be estimated that 5000 characters will be stored in the character array without specifying the length, the nearest power of 5000 is 4096, and 2 will be added for each expansion, then:
(1) on the basis of 4096, apply for 8194 character arrays, which is equivalent to applying for 12290 character arrays at one time. If 5000 character arrays can be specified at the beginning, more than double the space will be saved
(2) copy the original 4096 characters to the new character array
In this way, it not only wastes memory space, but also reduces code efficiency. Therefore, it is not wrong to set a reasonable initialization capacity for the underlying collections and tool classes implemented by arrays, which will bring immediate results. Note, however, that for a set like HashMap, which is implemented by array + linked list, don't set the initial size to the same as your estimated size, because the possibility of connecting only one object to a table is almost zero. The initial size is recommended to be set to the nth power of 2. If it can be estimated that there are 2000 elements, it can be set to new HashMap (128) and new HashMap (256).
10. When copying a large amount of data, use system Arraycopy() command
11. Multiplication and division use shift operation
For example:
for (val = 0; val < 100000; val += 5) { a = val * 8; b = val / 2; }
Using shift operation can greatly improve the performance, because the operation of bit alignment is the most convenient and fastest at the bottom of the computer. Therefore, it is recommended to modify it to:
for (val = 0; val < 100000; val += 5) { a = val << 3; b = val >> 1; }
Although the shift operation is fast, it may make the code difficult to understand, so it is best to add corresponding comments.
12. Do not create object references continuously in the loop
For example:
for (int i = 1; i <= count; i++) { Object obj = new Object(); }
This will cause count object references in memory. If the count is large, memory will be consumed. It is recommended to change to:
Object obj = null;for (int i = 0; i <= count; i++) { obj = new Object(); }
In this way, there is only one object object reference in memory. Each time a new object() is created, the object object reference points to a different object, but there is only one in memory, which greatly saves memory space.
13. In consideration of efficiency and type checking, array should be used as much as possible. ArrayList should be used only when the array size cannot be determined
14. Try to use HashMap, ArrayList and StringBuilder. Unless required by thread safety, hashtable, vector and StringBuffer are not recommended. The latter three lead to performance overhead due to the use of synchronization mechanism
15. Do not declare the array as public static final
Because this is meaningless, it only defines the reference as static final, and the contents of the array can be changed at will. Declaring the array as public is a security vulnerability, which means that the array can be changed by external classes
16. Try to use a single example in appropriate occasions
Using a singleton can reduce the load, shorten the loading time and improve the loading efficiency, but it is not applicable to singleton in all places. In short, singleton is mainly applicable to the following three aspects:
(1) control the use of resources, and control the concurrent access of resources through thread synchronization
(2) control the generation of examples to achieve the purpose of saving resources
(3) control the sharing of data and enable communication between multiple unrelated processes or threads without establishing direct correlation
17. Try to avoid using static variables at will
You should know that when an object is referenced by a variable defined as static, GC usually does not reclaim the heap memory occupied by the object, such as:
public class A { private static B b = new B(); }
At this time, the life cycle of static variable B is the same as that of class A. if class A is not unloaded, the B object pointed to by reference B will reside in memory until the program terminates
18. Clear unnecessary sessions in time
In order to clear inactive sessions, many application servers have a default session timeout of 30 minutes. When the application server needs to save more sessions, if the memory is insufficient, the operating system will transfer some data to disk, The application server may also be based on the MRU (most frequently used recently) the algorithm dumps some inactive sessions to disk, and may even throw an exception of insufficient memory. If a session is to be dumped to disk, it must be serialized first. In large-scale clusters, the cost of serializing objects is very expensive. Therefore, when the session is no longer needed, the invalidate() of httpsession should be called in time Method to clear the session.
19. Collections that implement the randomaccess interface, such as ArrayList, should be traversed by the most common for loop rather than foreach loop
This is recommended by JDK to users. The JDK API explains the randomaccess interface as follows: the randomaccess interface is implemented to show that it supports fast random access. The main purpose of this interface is to allow general algorithms to change their behavior, so that it can provide good performance when applied to random or continuous access lists. Practical experience shows that if the class instance implementing randomaccess interface is accessed randomly, the efficiency of using ordinary for loop will be higher than that of using foreach loop; Conversely, if it is accessed sequentially, it is more efficient to use iterator. A code similar to the following can be used for judgment:
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 principle of foreach loop is iterator. See Java syntax sugar 1: variable length parameters and the principle of foreach loop. So the second half of the sentence & rdquo; Conversely, if it is accessed sequentially, it is more efficient to use iterator & rdquo; It means that those class instances accessed sequentially are traversed by using the foreach loop.
20. Use synchronization code block instead of synchronization method
This has been made clear in the synchronized lock method block in the multithreading module. Unless it is determined that the whole method needs to be synchronized, try to use the synchronized code block to avoid synchronizing the code that does not need to be synchronized, which affects the code execution efficiency.
21. Declare the constant as static final and name it in uppercase
In this way, these contents can be put into the constant pool during compilation to avoid calculating the value of the generated constant during runtime. In addition, it is also convenient to distinguish constants from variables by naming constants in uppercase
22. Do not create some unused objects or import some unused classes
This makes no sense if & rdquo; appears in the code; The value of the local variable i is not used”、& rdquo; The import java. util is never used”, Then please delete these useless contents
23. Avoid using reflection during program operation
For, see reflections. Reflection is a very powerful function provided by java to users. Powerful function often means low efficiency. It is not recommended to use the reflection mechanism, especially the invoke method of method, frequently during program operation. If necessary, a recommended approach is to instantiate the classes that need to be loaded through reflection and put them into memory & mdash- Users only care about getting the fastest response speed when interacting with the opposite end, and they don't care how long it takes to start the opposite end project.
24. Use database connection pool and thread pool
Both pools are used to reuse objects. The former can avoid frequent opening and closing connections, and the latter can avoid frequent creation and destruction of threads
25. Use buffered I / O stream for IO operation
Buffered input / output streams, i.e. BufferedReader, bufferedwriter, bufferedinputstream and bufferedoutputstream, can greatly improve IO efficiency
26. ArrayList is used for scenes with more sequential insertion and random access, and LinkedList is used for scenes with more element deletion and intermediate insertion
You can understand the principles of ArrayList and LinkedList
27. Don't let the public method have too many formal parameters
Public methods are externally provided methods. If these methods are given too many formal parameters, they have two disadvantages:
1. It violates the idea of object-oriented programming. Java emphasizes that everything is an object. Too many formal parameters do not agree with the idea of object-oriented programming
2. Too many parameters will inevitably increase the error probability of method call
As for this & rdquo; Too many & rdquo; How many do you mean? Three or four. For example, we use JDBC to write an insertstudentinfo method. There are 10 student information fields to be inserted into the student table. These 10 parameters can be encapsulated in an entity class as formal parameters of the insert method
28. Write the string constant in front of the string variable and string constant equals
This is a common trick. If you have the following code:
String str = "123"; if (str.equals("123")) { ... }
It is suggested to amend to read:
String str = "123"; if ("123".equals(str)) { ... }
This is mainly to avoid null pointer exceptions
29. Please know that there is no difference between if (I = = 1) and if (1 = = I) in Java, but in terms of reading habits, it is recommended to use the former
Usually someone asks, & rdquo; if (i == 1)” And & rdquo; if (1== i)” There is no difference, which starts with C / C + +.
In C / C + +, & rdquo; if (i == 1)” If the judgment condition is true, it is based on 0 and non-0. 0 means false and non-0 means true. If there is such a code:
int i = 2; if (i == 1) { ... }else{ ... }
C / C + + Judgment & rdquo; i==1″ Not true, so it is represented by 0, that is, false. However, if:
int i = 2;if (i = 1) { ... }else{ ... }
If a programmer is not careful, put & rdquo; if (i == 1)” Write & rdquo; if (i = 1)”, So there's a problem. If I is assigned to 1 within the if, if judges that the content is not 0 and returns true, but it is clear that I is 2 and the compared value is 1, which should return false. This situation is likely to occur in the development of C / C + + and will lead to some incomprehensible errors. Therefore, in order to avoid the developer's incorrect assignment operation in the if statement, it is recommended to write the if statement as:
int i = 2;if (1 == i) { ... }else{ ... }
In this way, even if the developer accidentally writes & rdquo; 1 = i”, The C / C + + compiler can also check it for the first time, because we can assign I to a variable as 1, but we can't assign 1 to a constant as I.
However, in Java, C / C + + is & rdquo; if (i = 1)” The syntax of is impossible, because once this syntax is written, Java will compile and report an error & rdquo; Type mismatch: cannot convert from int to boolean”。 However, despite Java's & rdquo; if (i == 1)” And & rdquo; if (1 == i)” There is no semantic difference, but in terms of reading habits, it is better to use the former.
30. Do not use the toString () method for arrays
Take a look at what is printed out by using toString () on an array:
public static void main(String[] args) { int[] is = new int[]{1, 2, 3}; System.out.println(is.toString()); }
The result is:
[I@18a992f
The original intention is to print out the contents of the array, but the null pointer exception may be caused because the array reference is is null. However, although it has no meaning for array tostring(), it can print the contents of the collection for collection tostring(), because the parent class abstractcollections < E > of the collection overrides the tostring() method of object.
31. Do not force downward transformation of basic data types beyond the scope
This will never get the desired results:
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 and 64 bits, so the representation of 12345678901234 in the computer should be:
0000 0000 0000 0000 0000 1011 0011 1010 0111 0011 1100 1110 0010 1111 1111 0010
An int type data is 4 bytes and 32 bits. The first 32 bits of the above string of binary data taken from the low bit are:
0111 0011 1100 1110 0010 1111 1111 0010
This string of binary is represented as decimal 1942892530, so it is the content output on our console above. Two conclusions can be drawn from this example:
1. The default data type of integer is int, long l = 12345678901234l. This number has exceeded the range of int, so there is an L at the end, indicating that it is a long number. Incidentally, the default type of floating point type is double, so when defining float, it should be written as & rdquo; "float f = 3.5f”
2. Write another sentence & rdquo; int ii = l + i;& rdquo; An error will be reported because long + int is a long and cannot be assigned to int
32. Unused data in public collection classes must be removed in time
If a collection class is public (that is, it is not an attribute in the method), then the elements in the collection will not be released automatically, because there are always references to them. Therefore, if some data in the public collection is not used and they are not removed, it will cause the public collection to grow continuously, resulting in the hidden danger of memory leakage in the system.
33. Convert a basic data type to a string, basic data type Tostring() is the fastest way, string Valueof (data) comes next, and data + & rdquo; "Slowest"
There are three ways to convert a basic data type to general. I have an integer data type I, which can use i.tostring(), string valueOf(i)、i+” "Three methods. How effective are the three methods? Let's take a test:
public static void main(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 + ""; } System.out.println("i + \"\":" + (System.currentTimeMillis() - startTime) + "ms"); }
The operation result is:
String.valueOf():11ms Integer.toString():5ms i + "":25ms
Therefore, when converting a basic data type to string in the future, the toString () method is preferred. As for why, it's simple:
1、String. The underlying valueof () method called integer Tostring() method, but short judgment will be made before calling
2、Integer. The toString () method will not be mentioned, but will be called directly
3、i + “& rdquo; The bottom layer is implemented by StringBuilder. Firstly, the append method is used to splice, and then the toString () method is used to obtain the string
In contrast, 2 is the fastest, 1 is the second, and 3 is the slowest
34. Use the most efficient way to traverse the map
There are many ways to traverse the map. In general, we need to traverse the key and value in the map. The recommended and most efficient way 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 the map, use & rdquo; Set
keySet = hm.keySet();& rdquo; It would be more appropriate
35. It is recommended to operate the close() of resources separately
For example, I have a piece of code:
try{ XXX.close(); YYY.close(); }catch (Exception e) { ... }
It is suggested to amend to read:
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 If close() throws an exception, it enters the CATH block, YYY If close() is not executed, YYY resource will not be recycled and will be occupied all the time. If there is too much code, the resource handle may be leaked. After changing to the following wording, it is guaranteed that XXX and YYY will be closed anyway.