Code optimization details
1. Try to specify that the final modifier of the class and method. Classes with final modifiers with final modifiers cannot be derived. In the Java core API, there are many examples of applying final, such as java.lang.String, and the entire class is final. Specifying a final modifier for a class can prevent the class from being inherited, and specifying a final modifier for a method can prevent 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 is of great significance to improving Java operation efficiency.
2. Try to reuse the use of objects, especially String objects. When string concatenation occurs, StringBuilder/StringBuffer should be used instead. Since Java virtual machines not only need to spend time generating objects, they may also need to spend time garbage collecting and processing these objects in the future, generating too many objects will have a great impact on the performance of the program.
3. Use local variables to call methods as much as possible. The parameters passed when calling methods and the temporary variables created in the call are stored on the stack faster. Other variables, such as static variables, instance variables, etc., are created in the heap, and the speed is slower. In addition, as the variables created in the stack are finished, these contents are gone and no additional garbage collection is required.
4. Close the flow in time
During Java programming, be careful when performing database connection and I/O streaming operations. After use, close it in time to release resources. Because the operation of these large objects will cause large system overhead, and if you are not careful, it will lead to serious consequences.
5. Try to minimize the repeated calculation of variables, clarify a concept. Even if there is only one sentence in the method, it is still consumed, including creating stack frames, protecting the site when calling the method, and restoring the site when calling the method. So for example, the following operation:
for(inti = 0; i < list.size(); i++)
{...} is recommended to replace it with:
for(inti = 0, length = list.size(); i < length; i++)
{...}
In this way, when list.size() is very large, it reduces a lot of consumption
6. Try to adopt a lazy loading strategy, that is, create it when needed
7. Use abnormalities with caution will be detrimental to performance. To throw an exception, you must 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. As long as 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. Don't use try...catch... in the loop, it should be placed on the outermost layer
According to the opinions put forward by netizens, I think this is worth discussing
9. If you can estimate the length of content to be added, specify the initial length for the collection and tool classes implemented in an array, such as ArrayList, LinkedLlist, StringBuilder, StringBuffer, HashMap, HashSet, etc. Take StringBuilder as an example:
(1) StringBuilder() // Default to allocate 16 characters (2) StringBuilder(int size) // Default to allocate 16 characters (3) StringBuilder(String str) // Default to allocate 16 characters + str.length() character space You can set its initialization capacity through the constructor of the class (here we refer not only to the StringBuilder above), which can significantly improve performance. For example, StringBuilder, length represents the number of characters that the current StringBuilder can maintain. Because when StringBuilder reaches its maximum capacity, it will increase its capacity to 2 times and add 2. Whenever StringBuilder reaches its maximum capacity, it will have to create a new character array and copy the old character array content to the new character array - this is a very performance-consuming operation. Just imagine, if you can estimate that 5000 characters are stored in the character array without specifying the length, the power of 2 closest to 5000 is 4096, and the 2 added to each expansion is regardless of the 2, then:
(1) Based on 4096, apply for 8194-sized character arrays, which add up to 12290-sized character arrays at once. If you can specify 5000-sized character arrays at the beginning, it will save more than twice the space (2) Copy the original 4096 characters into the new character array in this way, which will not only waste memory space but also reduce the code operation efficiency. Therefore, it is not wrong to set a reasonable initialization capacity for the collection and tool classes implemented in the underlying array, which will bring immediate results. However, note that collections like HashMap that are implemented in arrays + linked lists should not set the initial size the same as your estimated size, because the possibility of only one object connected to a table is almost 0. It is recommended to set the initial size to N power of 2. If you can estimate that there are 2,000 elements, set it to new HashMap(128) and new HashMap(256).
10. When copying a large amount of data, use the System.arraycopy() command
11. Multiplication and division use shift operations
12. Do not create object references continuously in the loop
For example:
for(inti = 1; i <= count; i++){ Object obj = newObject(); }This approach will cause the count object object reference to exist in the memory. If the count is large, it will consume memory. It is recommended to change it to:
Object obj = null;for(inti = 0; i <= count; i++){ obj = newObject();} In this way, there is only one Object object reference in memory. Every time new Object() is used, the Object object reference points to a different Object, but there is only one Object in memory, which greatly saves memory space.
13. Based on the 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 thread-safe requires it, it is not recommended to use Hashtable, Vector, and StringBuffer. The latter three have performance overhead due to the use of synchronization mechanisms.
15. Do not declare arrays as public static final
Because this is meaningless, it only defines the reference as static final, and the content of the array can still 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 singletons in suitable occasions. Using singletons can reduce the load burden, shorten the loading time, and improve loading efficiency. However, not all places are suitable for singletons. Simply put, singletons are mainly applicable to the following three aspects:
(1) Control the use of resources, control the concurrent access of resources through thread synchronization (2) Control the generation of instances 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 associations without establishing direct associations.
17. Try to avoid using static variables at will
public class A{ private static B b = newB(); } At this time, the life cycle of the static variable b is the same as that of Class A. If Class A is not uninstalled, the B object pointed to by reference B will be residing in memory until the program terminates
18. Clear no longer needed sessions in time. In order to clear no longer active sessions, many application servers have a default session timeout, generally 30 minutes. When the application server needs to save more sessions, if there is insufficient memory, the operating system will transfer part of the data to disk. The application server may also dump some inactive sessions to disk according to the MRU (most frequently used recently) algorithm, and may even throw insufficient memory exceptions. If the session is to be dumped to disk, it must be serialized first. In large-scale clusters, serializing objects is expensive. Therefore, when the session is no longer needed, the invalidate() method of HttpSession should be called in time to clear the session.
19. For collections that implement RandomAccess interfaces, such as ArrayList, you should use the most common for loop instead of foreach loop to traverse this is recommended by JDK to users. The JDK API's explanation of the RandomAccess interface is: implementing the RandomAccess interface is used to indicate 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 class instances that implement the RandomAccess interface are randomly accessed, the efficiency of using ordinary for loops will be higher than that of using foreach loops; conversely, if accessed sequentially, it will be more efficient to use Iterator. You can use codes similar to the following to make judgments:
if(list instanceofRandomAccess){ for(inti = 0; i < list.size(); i++){}}else{ Iterator<?> iterator = list.iterable(); while(iterator.hasNext()){iterator.next()}} The underlying implementation principle of foreach loop is the iterator, so the second half of the sentence "In turn, if it is accessed sequentially, using Iterator will be more efficient" means that the class instances that are accessed sequentially, and use the foreach loop to traverse.
20. Using synchronized code blocks instead of synchronization methods has been explained very clearly in the synchronized lock method block article in multi-threaded module. Unless it can be determined that the entire method needs to be synchronized, try to use synchronized code blocks to avoid synchronizing those codes that do not need to be synchronized, which affects the code execution efficiency.
21. Declare the constants as static final and name them in capital so that these contents can be put into the constant pool during compilation, avoiding the calculation of the generated constant values during runtime. In addition, naming the name of a constant in capital can also facilitate the distinction between constants and variables
22. Do not create some unused objects, do not import some unused classes
This makes no sense. If "The value of the local variable i is not used" and "The import java.util is never used" appear in the code, then please delete these useless contents
23. Avoid using reflection during the program operation. For more information, please see Reflection. Reflection is a very powerful function provided by Java to users. Powerful functions often means low efficiency. It is not recommended to use the reflection mechanism in the process of running the program, especially the method's invoke method. If it is indeed necessary, a suggestive approach is to instantiate an object through reflection and put it into memory when the project is started - the user only cares about the fastest response speed when interacting with the peer, and does not care how long it takes for the peer project to start.
24. Use database connection pool and thread pool, both pools, are used to reuse objects. The former can avoid frequent opening and closing of connections, and the latter can avoid frequent creation and destruction of threads.
25. Use buffered input and output streams for IO operations
Buffered input and output streams, namely BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream, which can greatly improve IO efficiency
26. Use ArrayList for scenes with more sequential insertion and random access, and use LinkedList for scenes with more element deletion and intermediate insertion.
This is known by understanding the principles of ArrayList and LinkedList
27. Don't let too many formal parameters in the public method
The public method is a method provided to the outside world. If you give these methods too many formal parameters, there are two main disadvantages:
1) Violating the object-oriented programming idea. Java emphasizes that everything is an object. Too many formal parameters are not in line with the object-oriented programming idea.
2) Too many parameters will inevitably lead to an increase in the probability of error in the method call. As for how many "too many" refers to, 3 or 4. 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. When writing string variables and string constants equals, it is a relatively common trick to write string constants in front. If there is the following code:
String str = "123";if(str.equals("123")){ ...} It is recommended to modify it to:
String str = "123";if("123".equals(str)){ ...} This can mainly avoid null pointer exceptions
32. Do not force downward transformation of basic data types beyond the scope
33. Convert a basic data type into a string. The basic data type.toString() is the fastest way, followed by String.valueOf (data), and data + "The slowest way to convert a basic data type into three ways. I have an Integer type data i, which can use i.toString(), String.valueOf(i), i+ " ". How efficient are the three methods? See a test:
publicstatic void main(String[] args){ intloopTime = 50000; Integer i = 0; longstartTime = System.currentTimeMillis(); for(intj = 0; j < loopTime; j++) { String str = String.valueOf(i); } System.out.println("String.valueOf(): "+ (System.currentTimeMillis() - startTime) + "ms"); startTime = System.currentTimeMillis(); for(intj = 0; j < loopTime; j++) { String str = i.toString(); } System.out.println("Integer.toString():"+ (System.currentTimeMillis() - startTime) + "ms"); startTime = System.currentTimeMillis(); for(intj = 0; j < loopTime; j++) { String str = i + ""; } System.out.println("i + /"/":" + (System.currentTimeMillis() - startTime) + "ms");}The running result is:
String.valueOf(): 11msInteger.toString(): 5ms + "": 25ms
Therefore, when you convert a basic data type to String in the future, you should give priority to using the toString() method. As for why, it's very simple:
1. The String.valueOf() method is called the Integer.toString() method at the bottom, but it will make a short judgment before calling.
2. I won’t talk about the Integer.toString() method, I will call it directly.
3. The bottom layer of i + "" uses StringBuilder to implement it. First use the append method to splice it, and then use the toString() method to get the string. It is obviously the fastest 2, the fastest 1, and the slowest 3.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.