国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

J2EE系統(tǒng)優(yōu)化的幾點(diǎn)體會(huì)(二、循環(huán))

2019-11-18 16:04:01
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  條例二:在循環(huán)處,多下功夫

循環(huán)作為程序編寫的基本語(yǔ)法,可以說(shuō)是隨處可見。一些小的細(xì)節(jié)能帶來(lái)性能上的提升,而對(duì)循環(huán)體的一些改寫,能帶來(lái)性能的大幅提升。

比如最簡(jiǎn)單的List遍歷,會(huì)有這樣的寫法:for(int i=0;i
同樣是對(duì)List的操作,如果要在遍歷同時(shí)進(jìn)行增加和刪除操作,代碼如下:for(int i=0,j=l.size();i=0;i--){l.remove(i);}。經(jīng)過(guò)測(cè)試,如果采用ArrayList,兩種寫法在循環(huán)次數(shù)較少時(shí)沒有太大的區(qū)別,循環(huán)次數(shù)為1000,均為1ms以內(nèi),次數(shù)為10000,前一種為60ms左右,后一種為1ms以內(nèi),,而次數(shù)上到100000,前一種為6000ms左右,后一種為15ms,隨著循環(huán)次數(shù)的增多,后一種較前一種的效率優(yōu)勢(shì)明顯提高。
這是由Collection庫(kù)ArrayList的實(shí)現(xiàn)決定的,以下是jdk1.3的ArrayList源碼
public Object remove(int index) {
RangeCheck(index);
modCount++;
Object oldValue = elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
從中我們可以看出,numMoved代表了需要進(jìn)行arraycopy操作的數(shù)量,它是由remove的位置決定的,如果index=0,也就是刪除第一個(gè)元素,則需要arraycopy后面的所有數(shù)據(jù),
而如果index=size-1,則只需將最后一個(gè)元素設(shè)為null即可。所以從后面向前循環(huán)remove是比較好的寫法。
如果List中的確存在較多的add或remove操作,且容量較大(如存儲(chǔ)幾萬(wàn)個(gè)對(duì)象),則應(yīng)該采用LinkedList作為實(shí)現(xiàn)。LinkedList內(nèi)部采用雙向鏈表作為數(shù)據(jù)結(jié)構(gòu),比ArrayList占用較多內(nèi)存空間,且隨機(jī)訪問(wèn)操作較慢(需要從頭或尾循環(huán)到相應(yīng)位置),但插入刪除操作很快(僅需進(jìn)行鏈表操作,無(wú)須大量移動(dòng)或拷貝)。
對(duì)于List操作如果循環(huán)規(guī)模較小,其實(shí)對(duì)性能影響非常小(ms級(jí)),遠(yuǎn)遠(yuǎn)不是性能瓶頸所在。但心中有著優(yōu)化的意識(shí),并力求寫出簡(jiǎn)潔高效的程序應(yīng)該是我們每個(gè)程序員的追求。而且一旦在循環(huán)規(guī)模較大時(shí),如果有了這些意識(shí),也就能有效的消除性能隱患。
再舉一個(gè)與優(yōu)化無(wú)關(guān)但確實(shí)可能成為性能殺手(可以說(shuō)是bug)的循環(huán)的例子。下面是源代碼:
for(; totalRead < m_totalBytes; totalRead += readBytes)
{
readBytes = m_request.getInputStream().read(m_binArray, totalRead, m_totalBytes - totalRead);
}
這個(gè)代碼意圖很清楚,就是將一個(gè)InputStream流讀到一個(gè)byte數(shù)組中去。它使用read方法循環(huán)讀取InputStream,該方法返回讀取的字節(jié)數(shù)。正常情況下,該循環(huán)運(yùn)行良好,當(dāng)totalRead=m_totalBytes時(shí),結(jié)束循環(huán),byte數(shù)組被正常填充。但如果仔細(xì)看一下InputStream的read方法的說(shuō)明,了解一下其返回值就會(huì)發(fā)現(xiàn),返回值可能為-1,即已讀到InputStream末尾再繼續(xù)讀時(shí)。如果發(fā)生讀取異常,可能出現(xiàn)這個(gè)問(wèn)題,而這個(gè)循環(huán)沒有檢查readBytes值是否為-1就往totalRead上加,這樣再次進(jìn)入循環(huán)體繼續(xù)讀取InputStream,又返回-1,繼續(xù)循環(huán)。如此循環(huán)直到int溢出才會(huì)跳出循環(huán)。而這個(gè)循環(huán)也就成了實(shí)實(shí)在在的CPU殺手,可以占去大量的CPU時(shí)間(取決于操作系統(tǒng))。其實(shí)解決很簡(jiǎn)單,對(duì)readBytes進(jìn)行判斷,如果為-1則跳出循環(huán)。
這個(gè)例子告訴我們:對(duì)循環(huán)一定要搞清循環(huán)的循環(huán)規(guī)模、每次循環(huán)體執(zhí)行時(shí)間、循環(huán)結(jié)束條件包括異常情況等,只有這樣才能寫出高效且沒有隱患的代碼。

(出處:http://m.survivalescaperooms.com)



發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 桐梓县| 石楼县| 西和县| 昌吉市| 潍坊市| 象州县| 金溪县| 苍溪县| 东乌| 商丘市| 赫章县| 汶川县| 勐海县| 马山县| 潍坊市| 兴义市| 施甸县| 桦川县| 治县。| 灵寿县| 库伦旗| 丰镇市| 黄浦区| 化德县| 宁津县| 黄石市| 攀枝花市| 靖安县| 栾川县| 卫辉市| 正蓝旗| 海晏县| 和田县| 德保县| 永城市| 金沙县| 富顺县| 星座| 安庆市| 平度市| 靖西县|