35个Java代码性能优化总结
代碼優(yōu)化的目標(biāo)是:
1、減小代碼的體積
2、提高代碼運(yùn)行的效率
代碼優(yōu)化細(xì)節(jié):
1、盡量指定類(lèi)、方法的final修飾符
帶有final修飾符的類(lèi)是不可派生的。為類(lèi)指定final修飾符可以讓類(lèi)不可以被繼承,為方法指定final修飾符可以讓方法不可以被重寫(xiě)。
2、盡量重用對(duì)象
特別是String對(duì)象的使用,出現(xiàn)字符串連接時(shí)應(yīng)該使StringBuilder/StringBuffer代替。
3、盡可能使用局部變量
調(diào)用方法時(shí)傳遞的參數(shù)以及在調(diào)用中創(chuàng)建的臨時(shí)變量都保存在棧中速度較快,其他變量,如靜態(tài)變量、實(shí)例變量等,都在堆中創(chuàng)建,速度較慢。另外,棧中創(chuàng)建的變量,隨著方法的運(yùn)行結(jié)束,這些內(nèi)容就沒(méi)了,不需要額外的垃圾回收。
4、及時(shí)關(guān)閉流
5、盡量減少對(duì)變量的重復(fù)計(jì)算
明確一個(gè)概念,對(duì)方法的調(diào)用,即使方法中只有一句語(yǔ)句,也是有消耗的,包括創(chuàng)建棧幀、調(diào)用方法時(shí)保護(hù)現(xiàn)場(chǎng)、調(diào)用方法完畢時(shí)恢復(fù)現(xiàn)場(chǎng)等。所以例如下面的操作:
for (int i = 0; i < list.size(); i++){...}建議替換為:
for (int i = 0, int length = list.size(); i < length; i++){...}這樣,在list.size()很大的時(shí)候,就減少了很多的消耗
6、盡量采用懶加載的策略,即在需要的時(shí)候才創(chuàng)建
7、慎用異常
8、不要在循環(huán)中使用try…catch…,應(yīng)該把其放在最外層
9、如果能估計(jì)到待添加的內(nèi)容長(zhǎng)度,為底層以數(shù)組方式實(shí)現(xiàn)的集合、工具類(lèi)指定初始長(zhǎng)度
因?yàn)楫?dāng)StringBuilder達(dá)到最大容量的時(shí)候,它會(huì)將自身容量增加到當(dāng)前的2倍再加2,無(wú)論何時(shí)只要StringBuilder達(dá)到它的最大容量,它就不得不創(chuàng)建一個(gè)新的字符數(shù)組然后將舊的字符數(shù)組內(nèi)容拷貝到新字符數(shù)組中—-這是十分耗費(fèi)性能的一個(gè)操作。
10、當(dāng)復(fù)制大量數(shù)據(jù)時(shí),使用System.arraycopy()命令
11、乘法和除法使用移位操作
用移位操作可以極大地提高性能,因?yàn)樵谟?jì)算機(jī)底層,對(duì)位的操作是最方便、最快的,因此建議修改為:
for (val = 0; val < 100000; val += 5){a = val << 3;b = val >> 1;}移位操作雖然快,但是可能會(huì)使代碼不太好理解,因此最好加上相應(yīng)的注釋。
12、循環(huán)內(nèi)不要不斷創(chuàng)建對(duì)象引用
例如:
for (int i = 1; i <= count; i++){Object obj = new Object();}這種做法會(huì)導(dǎo)致內(nèi)存中有count份Object對(duì)象引用存在,count很大的話,就耗費(fèi)內(nèi)存了,建議為改為:
Object obj = null;for (int i = 0; i <= count; i++) { obj = new Object(); }
13、基于效率和類(lèi)型檢查的考慮,應(yīng)該盡可能使用array,無(wú)法確定數(shù)組大小時(shí)才使用ArrayList。
14、盡量使用HashMap、ArrayList、StringBuilder,除非線程安全需要,否則不推薦使用Hashtable、Vector、StringBuffer,后三者由于使用同步機(jī)制而導(dǎo)致了性能開(kāi)銷(xiāo)。
15、不要將數(shù)組聲明為public?static?final
因?yàn)檫@毫無(wú)意義,這樣只是定義了引用為static?final,數(shù)組的內(nèi)容還是可以隨意改變的,將數(shù)組聲明為public更是一個(gè)安全漏洞,這意味著這個(gè)數(shù)組可以被外部類(lèi)所改變。
16、盡量在合適的場(chǎng)合使用單例
17、盡量避免隨意使用靜態(tài)變量
要知道,當(dāng)某個(gè)對(duì)象被定義為static的變量所引用,那么gc通常是不會(huì)回收這個(gè)對(duì)象所占有的堆內(nèi)存的,如:
public class A{ private static B b = new B();}此時(shí)靜態(tài)變量b的生命周期與A類(lèi)相同,如果A類(lèi)不被卸載,那么引用B指向的B對(duì)象會(huì)常駐內(nèi)存,直到程序終止。18、及時(shí)清除不再需要的會(huì)話
19、實(shí)現(xiàn)RandomAccess接口的集合比如ArrayList,應(yīng)當(dāng)使用最普通的for循環(huán)而不是foreach循環(huán)來(lái)遍歷
實(shí)現(xiàn)RandomAccess接口的類(lèi)實(shí)例,假如是隨機(jī)訪問(wèn)的,使用普通for循環(huán)效率將高于使用foreach循環(huán);反過(guò)來(lái),如果是順序訪問(wèn)的,則使用Iterator會(huì)效率更高。
可以使用類(lèi)似如下的代碼作判斷:
if (list instanceof RandomAccess){ for (int i = 0; i < list.size(); i++){}else{Iterator<?> iterator = list.iterable(); while (iterator.hasNext()){iterator.next();}}foreach循環(huán)的底層實(shí)現(xiàn)原理就是迭代器Iterator,所以后半句”反過(guò)來(lái),如果是順序訪問(wèn)的,則使用Iterator會(huì)效率更高”的意思就是順序訪問(wèn)的那些類(lèi)實(shí)例,使用foreach循環(huán)去遍歷。20、使用同步代碼塊替代同步方法
21、將常量聲明為static?final,并以大寫(xiě)命名
22、不要?jiǎng)?chuàng)建一些不使用的對(duì)象,不要導(dǎo)入一些不使用的類(lèi)
23、程序運(yùn)行過(guò)程中避免使用反射
24、使用數(shù)據(jù)庫(kù)連接池和線程池
25、使用帶緩沖的輸入輸出流進(jìn)行IO操作
帶緩沖的輸入輸出流,即BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,這可以極大地提升IO效率。
26、順序插入和隨機(jī)訪問(wèn)比較多的場(chǎng)景使用ArrayList,元素刪除和中間插入比較多的場(chǎng)景使用LinkedList。
27、不要讓public方法中有太多的形參,可以封裝成對(duì)象使用。
28、字符串變量和字符串常量equals的時(shí)候?qū)⒆址A繉?xiě)在前面。
29、不重要。。。略
30、不要對(duì)數(shù)組使用toString()方法
31、不重要。。。略
32、公用的集合類(lèi)中不使用的數(shù)據(jù)一定要及時(shí)remove掉
如果一個(gè)集合類(lèi)是公用的(也就是說(shuō)不是方法里面的屬性),那么這個(gè)集合里面的元素是不會(huì)自動(dòng)釋放的,因?yàn)槭冀K有引用指向它們。所以,如果公用集合里面的某些數(shù)據(jù)不使用而不去remove掉它們,那么將會(huì)造成這個(gè)公用集合不斷增大,使得系統(tǒng)有內(nèi)存泄露的隱患。
33、把一個(gè)基本數(shù)據(jù)類(lèi)型轉(zhuǎn)為字符串,基本數(shù)據(jù)類(lèi)型.toString()是最快的方式、String.valueOf(數(shù)據(jù))次之、數(shù)據(jù)+””最慢。
1、String.valueOf()方法底層調(diào)用了Integer.toString()方法,但是會(huì)在調(diào)用前做空判斷
2、Integer.toString()方法就不說(shuō)了,直接調(diào)用了
3、i?+?“”底層使用了StringBuilder實(shí)現(xiàn),先用append方法拼接,再用toString()方法獲取字符串
34、不重要。。。略
35、對(duì)資源的close()建議分開(kāi)操作
比如我有這么一段代碼:
try{XXX.close();YYY.close();}catch (Exception e){...}建議修改為:
try{ XXX.close(); }catch (Exception e) { ... }try{ YYY.close(); }catch (Exception e) {... }雖然有些麻煩,卻能避免資源泄露。我們想,如果沒(méi)有修改過(guò)的代碼,萬(wàn)一XXX.close()拋異常了,那么就進(jìn)入了cath塊中了,YYY.close()不會(huì)執(zhí)行,YYY這塊資源就不會(huì)回收了,一直占用著,這樣的代碼一多,是可能引起資源句柄泄露的。而改為下面的寫(xiě)法之后,就保證了無(wú)論如何XXX和YYY都會(huì)被close掉。
轉(zhuǎn)載于:https://www.cnblogs.com/archermeng/p/7537530.html
總結(jié)
以上是生活随笔為你收集整理的35个Java代码性能优化总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 通过Nagios监控weblogic服务
- 下一篇: Android笔记(七十) AlertD