Home >Java >javaTutorial >Java development code performance optimization summary

Java development code performance optimization summary

黄舟
黄舟Original
2017-02-06 13:11:471420browse

Code optimization may sound useless to some people. But I think you should try your best to develop good habits during the development process. If you accumulate small optimization points one by one, you will definitely see a significant improvement in efficiency. of. Okay, let me share with you the summary that I usually see used.


The goal of code optimization


1 Reduce the code size

2 Improve the performance of the entire system Running efficiency


Code details optimization


1 Try to specify the final modifier of the class and method


Classes with final modification are not derived. In the Java core API, there are many examples of using final, such as java.lang.String. The entire class is final. Specifying the final modifier for a class can prevent the class from being inherited, and specifying final for a method can prevent the method from being inherited. was rewritten. If you specify a class as final, all methods of the class are final. The Java compiler will look for opportunities to inline all final methods. Inlining plays a significant role in improving Java running efficiency. For details, see Java runtime optimization. This can improve performance by an average of 50%.


2 Try to reuse objects


Especially when using String objects, StringBuilder/ should be used when string connections occur. StringBuffer instead. Since the Java virtual machine not only spends time generating objects, it may also need to spend time garbage collecting and processing these objects in the future. Therefore, generating too many objects will have a great impact on the performance of the program.


3 Use local objects whenever possible


#The parameters passed when calling the method and the temporary variables created in the call They are all saved in the stack and are faster. Other variables, such as static variables and instance variables, are created in the heap and are slower. In addition, the contents of variables created in the stack are gone as the method ends, and no additional garbage collection is required.


4 Close the stream in a timely manner


#During the Java programming process, be sure to perform database connections and I/O stream operations Be careful to close it promptly after use to release resources. Because operating these large objects will cause a lot of system overhead, a little carelessness will lead to serious consequences.


5 Try to reduce the repeated calculation of variables


Clear a concept, the call to the method, even if the method There is only one statement, which is also expensive, including creating a stack frame, protecting the scene when calling the method, restoring the scene when the method is called, etc. So for example, the following operation:

for (int i = 0; i < list.size(); i++)
{...}

is recommended to be replaced by:

for (int i = 0, int length = list.size(); i < length; i++)
{...}

In this way, when list.size() is very large, a lot of consumption is reduced

6 Try to adopt a lazy loading strategy, that is, create it only when needed.


For example:

String str = "aaa";if (i == 1)
{
list.add(str);
}

is recommended to be replaced with:

if (i == 1)
{String str = "aaa";
list.add(str);
}

7 Use exceptions with caution


Exceptions are bad for 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. Whenever an exception is thrown, the Java virtual machine must adjust the call stack because a new object is created during processing. Exceptions should only be used for error handling and should not be used to control program flow.


8 Don't use try...catch... in a loop. It should be placed outside

unless you have to. If you write this without any reason, as long as your leader is more senior and has more obsessive-compulsive disorder, he will probably scold you for writing such garbage code


9. If the length of the content to be added can be estimated, specify the initial length for the underlying collection and tool class implemented in array


such as ArrayList, LinkedLlist, StringBuilder, StringBuffer, HashMap , HashSet, etc., taking StringBuilder as an example:


(1) StringBuilder() // Allocate 16 characters of space by default

(2) StringBuilder (int size) // The default allocation is size character space

(3) StringBuilder(String str) // The default allocation is 16 characters + str.length() character space


You can set its initialization capacity through the class (here refers to not only the above StringBuilder), which can significantly improve performance. For example, StringBuilder, length represents the number of characters that the current StringBuilder can hold. Because when StringBuilder reaches its maximum capacity, it will increase its capacity to 2 times its current capacity plus 2. Whenever StringBuilder reaches its maximum capacity, it has to create a new character array and then replace the old characters with The contents of the array are copied into a new character array - this is a very performance-intensive operation. Just imagine, if it can be estimated that approximately 5000 characters will be stored in the character array without specifying the length, the closest power of 2 to 5000 is 4096, and 2 is added for each expansion, then:


(1) On the basis of 4096, apply for 8194 character arrays. The total is equivalent to applying for 12290 character arrays at one time. If you can specify a character array of 5000 sizes at the beginning, This saves more than double the space


(2) Copy the original 4096 characters to the new character array

这样,既浪费内存空间又降低代码运行效率。所以,给底层以数组实现的集合、工具类设置一个合理的初始化容量是错不了的,这会带来立竿见影的效果。但是,注意,像HashMap这种是以数组+链表实现的集合,别把初始大小和你估计的大小设置得一样,因为一个table上只连接一个对象的可能性几乎为0。初始大小建议设置为2的N次幂,如果能估计到有2000个元素,设置成new  HashMap(128)、new HashMap(256)都可以。


10 当复制大量数据时,使用 System.arraycopy() 命令


11 乘法和除法使用移位操作


例如:

for (val = 0; val < 100000; val += 5)
{
a = val * 8;
b = val / 2;
}

用移位操作可以极大地提高性能,因为在计算机底层,对位的操作是最方便、最快的,因此建议修改为:

for (val = 0; val < 100000; val += 5)
{
a = val << 3;
b = val >> 1;
}

移位操作虽然快,但是可能会使代码不太好理解,因此最好加上相应的注释。

12 循环内不要不断创建对象引用


例如:

for (int i = 1; i <= count; i++)
{Object obj = new Object();
}

这种做法会导致内存中有count份Object对象引用存在,count很大的话,就耗费内存了,建议为改为:Object obj = null;for (int i = 0; i <= count; i++) { obj = new Object(); }
这样的话,内存中只有一份Object对象引用,每次new Object()的时候,Object对象引用指向不同的Object罢了,但是内存中只有一份,这样就大大节省了内存空间了。

13基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组大小时才使用ArrayList


14尽量使用HashMap、ArrayList、StringBuilder,除非线程安全需要,否则不推荐使用Hashtable、Vector、StringBuffer,后三者由于使用同步机制而导致了性能开销


15 不要将数组声明为 public static final


因为这毫无意义,这样只是定义了引用为 static final ,数组的内容还是可以随意改变的,将数组声明为 public 更是一个安全漏洞,这意味着这个数组可以被外部类所改变


16 尽量在合适的场合使用单例


使用单例可以减轻加载的负担、缩短加载的时间、提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:


(1)控制资源的使用,通过线程同步来控制资源的并发访问

(2)控制实例的产生,以达到节约资源的目的

(3)控制数据的共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信


17 尽量避免随意使用静态变量


要知道,当某个对象被定义为 static 的变量所引用,那么 gc 通常是不会回收这个对象所占有的堆内存的,如:

public class A{private static B b = new B();
}

以上就是Java开发代码性能优化总结的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn