java代碼優(yōu)化編程

可供程序利用的資源(內(nèi)存台囱、CPU時間、網(wǎng)絡(luò)帶寬等)是有限的读整,優(yōu)化的目的就是讓程序用盡可能

少的資源完成預(yù)定的任務(wù)簿训。優(yōu)化通常包含兩方面的內(nèi)容:減小代碼的體積,提高代碼的運(yùn)行效率米间。

本文討論的主要是如何提高代碼的效率煎楣。

在Java程序中,性能問題的大部分原因并不在于Java語言车伞,而是在于程序本身。養(yǎng)成好的代碼編

寫習(xí)慣非常重要喻喳,比如正確地另玖、巧妙地運(yùn)用java.lang.String類和java.util.Vector類,它能夠

顯著地提高程序的性能。下面我們就來具體地分析一下這方面的問題谦去。

1慷丽、盡量指定類的final修飾符帶有final修飾符的類是不可派生的。在Java核心API中鳄哭,有許多應(yīng)用

final的例子要糊,例如 java.lang.String。為String類指定final防止了人們覆蓋length()方法妆丘。另

外锄俄,如果指定一個類為final,則該類所有的方法都是final勺拣。Java編譯器會尋找機(jī)會內(nèi)聯(lián)(inline

)所有的final方法(這和具體的編譯器實(shí)現(xiàn)有關(guān))奶赠。此舉能夠使性能平均提高 50% 。

2药有、量重用對象毅戈。特別是String 對象的使用中,出現(xiàn)字符串連接情況時應(yīng)用StringBuffer 代替愤惰。

由于系統(tǒng)不僅要花時間生成對象苇经,以后可能還需花時間對這些對象進(jìn)行垃圾回收和處理。因此宦言,生

成過多的對象將會給程序的性能帶來很大的影響扇单。

3、盡量使用局部變量蜡励,調(diào)用方法時傳遞的參數(shù)以及在調(diào)用中創(chuàng)建的臨時變量都保存在棧(Stack)

中令花,速度較快。其他變量凉倚,如靜態(tài)變量兼都、實(shí)例變量等,都在堆(Heap)中創(chuàng)建稽寒,速度較慢扮碧。另外,

依賴于具體的編譯器/JVM杏糙,局部變量還可能得到進(jìn)一步優(yōu)化慎王。請參見《盡可能使用堆棧變量》。

4宏侍、不要重復(fù)初始化變量? 默認(rèn)情況下赖淤,調(diào)用類的構(gòu)造函數(shù)時, Java會把變量初始化成確定的值:

所有的對象被設(shè)置成null谅河,整數(shù)變量(byte咱旱、 short确丢、int、long)設(shè)置成0吐限,float和double變量

設(shè)置成0.0鲜侥,邏輯值設(shè)置成false。當(dāng)一個類從另一個類派生時诸典,這一點(diǎn)尤其應(yīng)該注意描函,因?yàn)橛胣ew

關(guān)鍵詞創(chuàng)建一個對象時,構(gòu)造函數(shù)鏈中的所有構(gòu)造函數(shù)都會被自動調(diào)用狐粱。

5舀寓、在JAVA + ORACLE 的應(yīng)用系統(tǒng)開發(fā)中,java中內(nèi)嵌的SQL語句盡量使用大寫的形式脑奠,以減輕

ORACLE解析器的解析負(fù)擔(dān)基公。

6、Java 編程過程中宋欺,進(jìn)行數(shù)據(jù)庫連接轰豆、I/O流操作時務(wù)必小心,在使用完畢后齿诞,及時關(guān)閉以釋放

資源酸休。因?yàn)閷@些大對象的操作會造成系統(tǒng)大的開銷,稍有不慎祷杈,會導(dǎo)致嚴(yán)重的后果斑司。

7、由于JVM的有其自身的GC機(jī)制但汞,不需要程序開發(fā)者的過多考慮宿刮,從一定程度上減輕了開發(fā)者負(fù)擔(dān)

,但同時也遺漏了隱患私蕾,過分的創(chuàng)建對象會消耗系統(tǒng)的大量內(nèi)存僵缺,嚴(yán)重時會導(dǎo)致內(nèi)存泄露,因此踩叭,

保證過期對象的及時回收具有重要意義磕潮。JVM回收垃圾的條件是:對象不在被引用;然而容贝,JVM的GC

并非十分的機(jī)智自脯,即使對象滿足了垃圾回收的條件也不一定會被立即回收。所以斤富,建議我們在對象

使用完畢膏潮,應(yīng)手動置成null。

8满力、在使用同步機(jī)制時戏罢,應(yīng)盡量使用方法同步代替代碼塊同步屋谭。

9、盡量減少對變量的重復(fù)計(jì)算

例如:for(int i = 0;i < list.size; i ++) {

}

應(yīng)替換為:

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

}

10龟糕、盡量采用lazy loading 的策略,即在需要的時候才開始創(chuàng)建悔耘。

例如:String str = “aaa”;

if(i == 1) {

list.add(str);

}

應(yīng)替換為:

if(i == 1) {

String str = “aaa”;

list.add(str);

}

11讲岁、慎用異常

異常對性能不利。拋出異常首先要創(chuàng)建一個新的對象衬以。Throwable接口的構(gòu)造函數(shù)調(diào)用名為

fillInStackTrace()的本地(Native)方法缓艳,fillInStackTrace()方法檢查堆棧,收集調(diào)用跟蹤信

息看峻。只要有異常被拋出阶淘,VM就必須調(diào)整調(diào)用堆棧,因?yàn)樵谔幚磉^程中創(chuàng)建了一個新的對象互妓。 異常

只能用于錯誤處理溪窒,不應(yīng)該用來控制程序流程。

12冯勉、不要在循環(huán)中使用:

Try {

} catch() {

}

應(yīng)把其放置在最外層澈蚌。

13、設(shè)定StringBuffer的初始化容量

StringBuffer表示了可變的灼狰、可寫的字符串宛瞄。

有三個構(gòu)造方法:

StringBuffer ();??????????? //默認(rèn)分配16個字符的空間

StringBuffer (int size);? //分配size個字符的空間

StringBuffer (String str);? //分配16個字符+str.length()個字符空間

你可以通過StringBuffer的構(gòu)造函數(shù)來設(shè)定它的初始化容量,這樣可以明顯地提升性能交胚。這里

提到的構(gòu)造函數(shù)是StringBuffer(int length)份汗,length參數(shù)表示當(dāng)前的StringBuffer能保持的字

符數(shù)量。你也可以使用ensureCapacity(int minimumcapacity)方法在StringBuffer對象創(chuàng)建之后

設(shè)置它的容量蝴簇。首先我們看看StringBuffer的缺省行為杯活,然后再找出一條更好的提升性能的途徑

StringBuffer在內(nèi)部維護(hù)一個字符數(shù)組军熏,當(dāng)你使用缺省的構(gòu)造函數(shù)來創(chuàng)建StringBuffer對象的

時候轩猩,因?yàn)闆]有設(shè)置初始化字符長度,StringBuffer的容量被初始化為16個字符荡澎,也就是說缺省容

量就是16個字符均践。當(dāng)StringBuffer達(dá)到最大容量的時候,它會將自身容量增加到當(dāng)前的2倍再加2摩幔,

也就是(2*舊值+2)彤委。如果你使用缺省值,初始化之后接著往里面追加字符或衡,在你追加到第16個字

符的時候它會將容量增加到34(2*16+2)焦影,當(dāng)追加到34個字符的時候就會將容量增加到 70

(2*34+2)车遂。無論何事只要StringBuffer到達(dá)它的最大容量它就不得不創(chuàng)建一個新的字符數(shù)組然后

重新將舊字符和新字符都拷貝一遍――這也太昂貴了點(diǎn)。所以總是給StringBuffer設(shè)置一個合理的

初始化容量值是錯不了的斯辰,這樣會帶來立竿見影的性能增益舶担。

StringBuffer初始化過程的調(diào)整的作用由此可見一斑。所以彬呻,使用一個合適的容量值來初始化

StringBuffer永遠(yuǎn)都是一個最佳的建議衣陶。

14、合理的使用Java類 java.util.Vector闸氮。

簡單地說剪况,一個Vector就是一個java.lang.Object實(shí)例的數(shù)組。Vector與數(shù)組相似蒲跨,它的元素

可以通過整數(shù)形式的索引訪問译断。但是,Vector類型的對象在創(chuàng)建之后或悲,對象的大小能夠根據(jù)元素的

增加或者刪除而擴(kuò)展孙咪、縮小。請考慮下面這個向Vector加入元素的例子:

Object obj = new Object();

Vector v = new Vector(100000);

for(int I=0;

I<100000; I++) { v.add(0,obj); }

除非有絕對充足的理由要求每次都把新元素插入到Vector的前面隆箩,否則上面的代碼對性能不利

该贾。在默認(rèn)構(gòu)造函數(shù)中,Vector的初始存儲能力是10個元素捌臊,如果新元素加入時存儲能力不足杨蛋,則以

后存儲能力每次加倍。Vector類就象StringBuffer類一樣理澎,每次擴(kuò)展存儲能力時逞力,所有現(xiàn)有的元素

都要復(fù)制到新的存儲空間之中。下面的代碼片段要比前面的例子快幾個數(shù)量級:

Object obj = new Object();

Vector v = new Vector(100000);

for(int I=0; I<100000; I++) { v.add(obj); }

同樣的規(guī)則也適用于Vector類的remove()方法糠爬。由于Vector中各個元素之間不能含有“空隙”

寇荧,刪除除最后一個元素之外的任意其他元素都導(dǎo)致被刪除元素之后的元素向前移動。也就是說执隧,從

Vector刪除最后一個元素要比刪除第一個元素“開銷”低好幾倍揩抡。

假設(shè)要從前面的Vector刪除所有元素,我們可以使用這種代碼:

for(int I=0; I<100000; I++)

{

v.remove(0);

}

但是镀琉,與下面的代碼相比峦嗤,前面的代碼要慢幾個數(shù)量級:

for(int I=0; I<100000; I++)

{

v.remove(v.size()-1);

}

從Vector類型的對象v刪除所有元素的最好方法是:

v.removeAllElements();

假設(shè)Vector類型的對象v包含字符串“Hello”∥菟ぃ考慮下面的代碼烁设,它要從這個Vector中刪除

“Hello”字符串:

String s = "Hello";

int i = v.indexOf(s);

if(I != -1) v.remove(s);

這些代碼看起來沒什么錯誤,但它同樣對性能不利钓试。在這段代碼中装黑,indexOf()方法對v進(jìn)行順

序搜索尋找字符串“Hello”副瀑,remove(s)方法也要進(jìn)行同樣的順序搜索。改進(jìn)之后的版本是:

String s = "Hello";

int i = v.indexOf(s);

if(I != -1) v.remove(i);

這個版本中我們直接在remove()方法中給出待刪除元素的精確索引位置恋谭,從而避免了第二次搜

索糠睡。一個更好的版本是:

String s = "Hello"; v.remove(s);

最后,我們再來看一個有關(guān)Vector類的代碼片段:

for(int I=0; I++;I < v.length)

如果v包含100,000個元素箕别,這個代碼片段將調(diào)用v.size()方法100,000次铜幽。雖然size方法是一

個簡單的方法,但它仍舊需要一次方法調(diào)用的開銷串稀,至少JVM需要為它配置以及清除堆棧環(huán)境。在

這里狮杨,for循環(huán)內(nèi)部的代碼不會以任何方式修改Vector類型對象v的大小母截,因此上面的代碼最好改寫

成下面這種形式:

int size = v.size(); for(int I=0; I++;I

雖然這是一個簡單的改動,但它仍舊贏得了性能橄教。畢竟清寇,每一個CPU周期都是寶貴的。

15护蝶、當(dāng)復(fù)制大量數(shù)據(jù)時华烟,使用System.arraycopy()命令。


更多資料每日分享加群 ? ? ?120342833 ? ? ?驗(yàn)證回答 ? ? ?ZZ

16持灰、代碼重構(gòu):增強(qiáng)代碼的可讀性盔夜。

例如:

public class ShopCart {

private List carts ;

public void add (Object item) {

if(carts == null) {

carts = new ArrayList();

}

crts.add(item);

}

public void remove(Object item) {

if(carts. contains(item)) {

carts.remove(item);

}

}

public List getCarts() {

//返回只讀列表

return Collections.unmodifiableList(carts);

}

//不推薦這種方式

//this.getCarts().add(item);

}

17、不用new關(guān)鍵詞創(chuàng)建類的實(shí)例

用new關(guān)鍵詞創(chuàng)建類的實(shí)例時堤魁,構(gòu)造函數(shù)鏈中的所有構(gòu)造函數(shù)都會被自動調(diào)用喂链。但如果一個對

象實(shí)現(xiàn)了Cloneable接口,我們可以調(diào)用它的clone()方法妥泉。clone()方法不會調(diào)用任何類構(gòu)造函數(shù)

椭微。

在使用設(shè)計(jì)模式(Design Pattern)的場合,如果用Factory模式創(chuàng)建對象盲链,則改用clone()方

法創(chuàng)建新的對象實(shí)例非常簡單蝇率。例如,下面是Factory模式的一個典型實(shí)現(xiàn):

public static Credit getNewCredit() {

return new Credit();

}

改進(jìn)后的代碼使用clone()方法刽沾,如下所示:

private static Credit BaseCredit = new Credit();

public static Credit getNewCredit() {

return (Credit) BaseCredit.clone();

}

上面的思路對于數(shù)組處理同樣很有用本慕。

18、乘法和除法

考慮下面的代碼:

for (val = 0; val < 100000; val +=5) {

alterX = val * 8; myResult = val * 2;

}

用移位操作替代乘法操作可以極大地提高性能悠轩。下面是修改后的代碼:

for (val = 0; val < 100000; val += 5) {

alterX = val << 3; myResult = val << 1;

}

修改后的代碼不再做乘以8的操作间狂,而是改用等價的左移3位操作,每左移1位相當(dāng)于乘以2火架。相

應(yīng)地鉴象,右移1位操作相當(dāng)于除以2忙菠。值得一提的是,雖然移位操作速度快纺弊,但可能使代碼比較難于理

解牛欢,所以最好加上一些注釋。

19淆游、在JSP頁面中關(guān)閉無用的會話傍睹。

一個常見的誤解是以為session在有客戶端訪問時就被創(chuàng)建,然而事實(shí)是直到某server端程序

調(diào)用HttpServletRequest.getSession(true)這樣的語句時才被創(chuàng)建犹菱,注意如果JSP沒有顯示的使

用<%@pagesession="false"%> 關(guān)閉session拾稳,則JSP文件在編譯成Servlet時將會自動加上這樣一

條語句HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的

session對象的來歷。由于session會消耗內(nèi)存資源腊脱,因此访得,如果不打算使用session,應(yīng)該在所有

的JSP中關(guān)閉它陕凹。

對于那些無需跟蹤會話狀態(tài)的頁面悍抑,關(guān)閉自動創(chuàng)建的會話可以節(jié)省一些資源。使用如下page指令:

<%@ page session="false"%>

20杜耙、JDBC與I/O

如果應(yīng)用程序需要訪問一個規(guī)模很大的數(shù)據(jù)集搜骡,則應(yīng)當(dāng)考慮使用塊提取方式。默認(rèn)情況下佑女,

JDBC每次提取32行數(shù)據(jù)记靡。舉例來說,假設(shè)我們要遍歷一個5000行的記錄集珊豹,JDBC必須調(diào)用數(shù)據(jù)庫

157次才能提取到全部數(shù)據(jù)簸呈。如果把塊大小改成512,則調(diào)用數(shù)據(jù)庫的次數(shù)將減少到10次店茶。

21蜕便、Servlet與內(nèi)存使用

許多開發(fā)者隨意地把大量信息保存到用戶會話之中。一些時候贩幻,保存在會話中的對象沒有及時

地被垃圾回收機(jī)制回收轿腺。從性能上看,典型的癥狀是用戶感到系統(tǒng)周期性地變慢丛楚,卻又不能把原因

歸于任何一個具體的組件族壳。如果監(jiān)視JVM的堆空間,它的表現(xiàn)是內(nèi)存占用不正常地大起大落趣些。

解決這類內(nèi)存問題主要有二種辦法仿荆。第一種辦法是,在所有作用范圍為會話的Bean中實(shí)現(xiàn)

HttpSessionBindingListener接口。這樣拢操,只要實(shí)現(xiàn)valueUnbound()方法锦亦,就可以顯式地釋放Bean

使用的資源。另外一種辦法就是盡快地把會話作廢令境。大多數(shù)應(yīng)用服務(wù)器都有設(shè)置會話作廢間隔時

間的選項(xiàng)杠园。另外,也可以用編程的方式調(diào)用會話的setMaxInactiveInterval()方法舔庶,該方法用來設(shè)

定在作廢會話之前抛蚁,Servlet容器允許的客戶請求的最大間隔時間,以秒計(jì)惕橙。

22瞧甩、使用緩沖標(biāo)記

一些應(yīng)用服務(wù)器加入了面向JSP的緩沖標(biāo)記功能。例如弥鹦,BEA的WebLogic Server從6.0版本開始

支持這個功能亲配,Open Symphony工程也同樣支持這個功能。JSP緩沖標(biāo)記既能夠緩沖頁面片斷惶凝,也能

夠緩沖整個頁面。當(dāng)JSP頁面執(zhí)行時犬钢,如果目標(biāo)片斷已經(jīng)在緩沖之中苍鲜,則生成該片斷的代碼就不用

再執(zhí)行。頁面級緩沖捕獲對指定URL的請求玷犹,并緩沖整個結(jié)果頁面混滔。對于購物籃、目錄以及門戶網(wǎng)

站的主頁來說歹颓,這個功能極其有用坯屿。對于這類應(yīng)用,頁面級緩沖能夠保存頁面執(zhí)行的結(jié)果巍扛,供后繼

請求使用领跛。

23、選擇合適的引用機(jī)制

在典型的JSP應(yīng)用系統(tǒng)中撤奸,頁頭吠昭、頁腳部分往往被抽取出來,然后根據(jù)需要引入頁頭胧瓜、頁腳矢棚。

當(dāng)前,在JSP頁面中引入外部資源的方法主要有兩種:include指令府喳,以及include動作蒲肋。

include 指令:例如<%@ include file="copyright.html" %>。該指令在編譯時引入指定的資

源。在編譯之前兜粘,帶有include指令的頁面和指定的資源被合并成一個文件申窘。被引用的外部資源在

編譯時就確定,比運(yùn)行時才確定資源更高效妹沙。

include動作:例如偶洋。該動作引入指定頁面執(zhí)行后生

成的結(jié)果。由于它在運(yùn)行時完成距糖,因此對輸出結(jié)果的控制更加靈活玄窝。但時,只有當(dāng)被引用的內(nèi)容頻

繁地改變時悍引,或者在對主頁面的請求沒有出現(xiàn)之前恩脂,被引用的頁面無法確定時,使用include 動作

才合算趣斤。

24俩块、及時清除不再需要的會話

為了清除不再活動的會話,許多應(yīng)用服務(wù)器都有默認(rèn)的會話超時時間浓领,一般為30分鐘玉凯。當(dāng)應(yīng)用

服務(wù)器需要保存更多會話時,如果內(nèi)存容量不足联贩,操作系統(tǒng)會把部分內(nèi)存數(shù)據(jù)轉(zhuǎn)移到磁盤漫仆,應(yīng)用服

務(wù)器也可能根據(jù)“最近最頻繁使用 ”(Most Recently Used)算法把部分不活躍的會話轉(zhuǎn)儲到磁

盤,甚至可能拋出“內(nèi)存不足”異常泪幌。在大規(guī)模系統(tǒng)中盲厌,串行化會話的代價是很昂貴的。當(dāng)會話不

再需要時祸泪,應(yīng)當(dāng)及時調(diào)用HttpSession.invalidate()方法清除會話吗浩。 HttpSession.invalidate()

方法通常可以在應(yīng)用的退出頁面調(diào)用没隘。

25懂扼、不要將數(shù)組聲明為:public static final 。

26升略、HashMap的遍歷效率討論

經(jīng)常遇到對HashMap中的key和value值對的遍歷操作微王,有如下兩種方法:Map<="" p="" style="word-wrap: break-word;">

[]> paraMap = new HashMap();

................//第一個循環(huán)

SetappFieldDefIds = paraMap.keySet();

for (String appFieldDefId : appFieldDefIds) {

String[] values = paraMap.get(appFieldDefId);

......

}

//第二個循環(huán)

for(Entryentry : paraMap.entrySet()){

String appFieldDefId = entry.getKey();

String[] values = entry.getValue();

.......

}

第一種實(shí)現(xiàn)明顯的效率不如第二種實(shí)現(xiàn)。

分析如下SetappFieldDefIds = paraMap.keySet(); 是先從HashMap中取得keySet

代碼如下:

public SetkeySet() {

Setks = keySet;

return (ks != null ? ks : (keySet = new KeySet()));

}

private class KeySet extends AbstractSet{

public Iteratoriterator() {

return newKeyIterator();

}

public int size() {

return size;

}

public boolean contains(Object o) {

return containsKey(o);

}

public boolean remove(Object o) {

return HashMap.this.removeEntryForKey(o) != null;

}

public void clear() {

HashMap.this.clear();

}

}

其實(shí)就是返回一個私有類KeySet, 它是從AbstractSet繼承而來品嚣,實(shí)現(xiàn)了Set接口炕倘。

再來看看for/in循環(huán)的語法

for(declaration : expression)

statement

在執(zhí)行階段被翻譯成如下各式

for(Iterator#i = (expression).iterator(); #i.hashNext();){

declaration = #i.next();

statement

}因此在第一個for語句for (String appFieldDefId : appFieldDefIds) 中調(diào)用了

HashMap.keySet().iterator() 而這個方法調(diào)用了newKeyIterator()

IteratornewKeyIterator() {

return new KeyIterator();

}

private class KeyIterator extends HashIterator{

public K next() {

return nextEntry().getKey();

}

}

所以在for中還是調(diào)用了

在第二個循環(huán)for(Entryentry : paraMap.entrySet())中使用的

Iterator是如下的一個內(nèi)部類

private class EntryIterator extends HashIterator {

public Map.Entrynext() {

return nextEntry();

}

}

此時第一個循環(huán)得到key,第二個循環(huán)得到HashMap的Entry

效率就是從循環(huán)里面體現(xiàn)出來的第二個循環(huán)此致可以直接取key和value值

而第一個循環(huán)還是得再利用HashMap的get(Object key)來取value值

現(xiàn)在看看HashMap的get(Object key)方法

public V get(Object key) {

Object k = maskNull(key);

int hash = hash(k);

int i = indexFor(hash, table.length); //Entry[] table

Entrye = table;

while (true) {

if (e == null)

return null;

if (e.hash == hash && eq(k, e.key))

return e.value;

e = e.next;

}

}

其實(shí)就是再次利用Hash值取出相應(yīng)的Entry做比較得到結(jié)果翰撑,所以使用第一中循環(huán)相當(dāng)于兩次

進(jìn)入HashMap的Entry中

而第二個循環(huán)取得Entry的值之后直接取key和value罩旋,效率比第一個循環(huán)高啊央。其實(shí)按照Map的概

念來看也應(yīng)該是用第二個循環(huán)好一點(diǎn),它本來就是key和value的值對涨醋,將key和value分開操作在這

里不是個好選擇瓜饥。

27、array(數(shù)組) 和 ArryList的使用

array([]):最高效浴骂;但是其容量固定且無法動態(tài)改變乓土;

ArrayList:容量可動態(tài)增長;但犧牲效率溯警;

基于效率和類型檢驗(yàn)趣苏,應(yīng)盡可能使用array,無法確定數(shù)組大小時才使用ArrayList梯轻!

ArrayList是Array的復(fù)雜版本

ArrayList內(nèi)部封裝了一個Object類型的數(shù)組食磕,從一般的意義來說,它和數(shù)組沒有本質(zhì)的差別

喳挑,甚至于ArrayList的許多方法彬伦,如Index、IndexOf伊诵、Contains单绑、Sort等都是在內(nèi)部數(shù)組的基礎(chǔ)上

直接調(diào)用Array的對應(yīng)方法。

ArrayList存入對象時曹宴,拋棄類型信息询张,所有對象屏蔽為Object,編譯時不檢查類型浙炼,但是運(yùn)

行時會報(bào)錯。

注:jdk5中加入了對泛型的支持唯袄,已經(jīng)可以在使用ArrayList時進(jìn)行類型檢查弯屈。

從這一點(diǎn)上看來,ArrayList與數(shù)組的區(qū)別主要就是由于動態(tài)增容的效率問題了

28恋拷、盡量使用HashMap 和ArrayList ,除非必要资厉,否則不推薦使用HashTable和Vector ,后者由于

使用同步機(jī)制蔬顾,而導(dǎo)致了性能的開銷宴偿。

29、StringBuffer 和StringBuilder的區(qū)別:

java.lang.StringBuffer 線程安全的可變字符序列诀豁。一個類似于 String 的字符串緩沖區(qū)窄刘,

但不能修改。StringBuilder舷胜。與該類相比娩践,通常應(yīng)該優(yōu)先使用 java.lang.StringBuilder類,因

為它支持所有相同的操作,但由于它不執(zhí)行同步翻伺,所以速度更快材泄。為了獲得更好的性能,在構(gòu)造

StirngBuffer 或 StirngBuilder 時應(yīng)盡可能指定它的容量吨岭。當(dāng)然拉宗,如果你操作的字符串長度不超

過16 個字符就不用了。 相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得

10%-15% 左右的性能提升辣辫,但卻要冒多線程不安全的風(fēng)險旦事。而在現(xiàn)實(shí)的模塊化編程中,負(fù)責(zé)某一模

塊的程序員不一定能清晰地判斷該模塊是否會放入多線程的環(huán)境中運(yùn)行络它,因此:除非你能確定你的

系統(tǒng)的瓶頸是在StringBuffer 上族檬,并且確定你的模塊不會運(yùn)行在多線程模式下,否則還是用

StringBuffer 吧化戳。

30.new的使用

循環(huán)內(nèi)不要創(chuàng)建對象

for(int i=1;i<=domainCount;i++){

.

AuditResult auditResult = new AuditResult();

..

}

這種做法會在內(nèi)存中保存N份這個對象的引用會浪費(fèi)大量的內(nèi)存空間单料,改為

AuditResult auditResult;

for(int i=1;i<=domainCount;i++){

.

auditResult=new AuditResult();

..

}

當(dāng)new創(chuàng)建對象不可避免時,注意避免多次的使用new初始化一個對象点楼。 盡量在使用時再創(chuàng)建該對

象扫尖。

NewObject object = new NewObject();

int value;

if(i>0 )

{

value =object.getValue();

}

改為

int value;

if(i>0 )

{

NewObject object = new NewObject();

Value =object.getValue();

4??????Q?LcC7

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掠廓,隨后出現(xiàn)的幾起案子换怖,更是在濱河造成了極大的恐慌,老刑警劉巖蟀瞧,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沉颂,死亡現(xiàn)場離奇詭異,居然都是意外死亡悦污,警方通過查閱死者的電腦和手機(jī)铸屉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來切端,“玉大人彻坛,你說我怎么就攤上這事√ぴ妫” “怎么了昌屉?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長茵瀑。 經(jīng)常有香客問我间驮,道長,這世上最難降的妖魔是什么马昨? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任蜻牢,我火速辦了婚禮烤咧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抢呆。我一直安慰自己煮嫌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布抱虐。 她就那樣靜靜地躺著昌阿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪恳邀。 梳的紋絲不亂的頭發(fā)上懦冰,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音谣沸,去河邊找鬼刷钢。 笑死,一個胖子當(dāng)著我的面吹牛乳附,可吹牛的內(nèi)容都是我干的内地。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赋除,長吁一口氣:“原來是場噩夢啊……” “哼阱缓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起举农,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤荆针,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后颁糟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航背,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年棱貌,在試婚紗的時候發(fā)現(xiàn)自己被綠了沃粗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡键畴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出突雪,到底是詐尸還是另有隱情起惕,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布咏删,位于F島的核電站惹想,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏督函。R本人自食惡果不足惜嘀粱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一激挪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锋叨,春花似錦垄分、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至偷卧,卻和暖如春豺瘤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背听诸。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工坐求, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晌梨。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓桥嗤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親派任。 傳聞我的和親對象是個殘疾皇子砸逊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法掌逛,內(nèi)部類的語法师逸,繼承相關(guān)的語法,異常的語法豆混,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 一皿伺、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,265評論 0 16
  • 一员辩、 1、請用Java寫一個冒泡排序方法 【參考答案】 public static void Bubble(int...
    獨(dú)云閱讀 1,375評論 0 6
  • 此文章出自:<a href="http://my.oschina.net/xianggao/blog/77224?...
    zlb閱讀 582評論 0 0
  • 周期是理財(cái)投資活動中最為關(guān)鍵的考量因素,如果不深入了解周期就沒法對趨勢進(jìn)行有效的判斷妒穴,那所做的投資可能就是沒有系統(tǒng)...
    大眼瑜閱讀 511評論 1 4