JAVA提高效能的文章

來源:互聯網
上載者:User
轉載自 www.matrix.org.cn

不知道以前有沒有人弄過,今天我來開個頭,希望大家能把自己的經驗貼出來,大家一起討論,對大家能夠寫出高效率的代碼有很大的協助。

我現來開個頭
這裡比較一下ArrayList和LinkedList:
1.ArrayList是基於數組,LinkedList基於鏈表實現。
2.對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標。
3.對於新增和刪除操作add和remove,LinedList比較佔優勢,因為ArrayList要移動資料。
4.尋找操作indexOf,lastIndexOf,contains等,兩者差不多。
這裡只是理論上分析,事實上也不一定,比如ArrayList在末尾插入和刪除資料就不設計到資料移動,不過還是
有這麼個建議:隨機訪問比較多的話一定要用ArrayList而不是LinkedList,如果需要頻繁的插入和刪除應該
考慮用LinkedList來提高效能。

multiple dimension array
Java裡面的multiple dimension array實際上是用array of arrays來類比的,這樣導致他們可能並非儲存在連續的記憶體空間,會引起比較糟糕的記憶體訪問的問題。

IBM的ninja group開發了一個package來解決這個問題,Array Package

減少不必要的對象的建立是提高效能的好辦法。
不僅對JAVA,所有語言都適用。
避免在迴圈條件中使用複雜運算式 在不做編譯最佳化的情況下,在迴圈中,迴圈條件會被反覆計算,如果不使用複雜運算式,而使迴圈條件值不變的話,程式將會啟動並執行更快。
為'Vectors' 和 'Hashtables'定義初始大小 JVM為Vector擴充大小的時候需要重新建立一個更大的數組,將原原先數組中的內容複寫過來,最後,原先的數組再被回收。可見Vector容量的擴大 是一個頗費時間的事。通常,預設的10個元素大小是不夠的。你最好能準確的估計你所需要的最佳大小
在finally塊中關閉Stream 程式中使用到的資源應當被釋放,以避免資源泄漏。這最好在finally塊中去做。不管程式執行的結果如何,finally塊總是會執行的,以確保資源的正確關閉。
使用'System.arraycopy ()'代替通過來迴圈複製數組
'System.arraycopy ()' 要比通過迴圈來複製數組快的多。
在一些知道迴圈次數的迴圈中使用short甚至byte.
好象很多人習慣用int
字串的串連儘可能使用stringbuffer
ava.lang.StringBuffer安全執行緒的可變字元序列。一個類似於 String 的字串緩衝區,但不能修改。雖然在任意時間點上它都包含某種特定的字元序列,但通過某些方法調用可以改變該序列的長度和內容。

可將字串緩衝區安全地用於多個線程。可以在必要時對這些方法進行同步,因此任意特定執行個體上的所有操作就好像是以串列順序發生的,該順序與所涉及的每個線程進行的方法調用順序一致。

StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類型的資料。每個方法都能有效地將給定的資料轉換成字串,然後將該字串的字元追加或插入到字串緩衝區中。 append 方法始終將這些字元添加到緩衝區的末端;而 insert 方法則在指定的點添加字元。

例如,如果 z 引用一個當前內容是“start”的字串緩衝區對象,則此方法調用 z.append("le") 會使字串緩衝區包含“startle”,而 z.insert(4, "le") 將更改字串緩衝區,使之包含“starlet”。

通常,如果 sb 引用 StringBuilder 的一個執行個體,則 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。

只要發生有關源序列(如在源序列中追加或插入)的操作,該類就只在執行此操作的字串緩衝區上而不是在源上實現同步。

每 個字串緩衝區都有一定的容量。只要字串緩衝區所包含的字元序列的長度沒有超出此容量,就無需分配新的內部緩衝區數組。如果內部緩衝區溢位,則此容量自 動增大。從 JDK 5 開始,為該類補充了一個單個線程使用的等價類別,即 StringBuilder。與該類相比,通常應該優先使用 StringBuilder 類,因為它支援所有相同的操作,但由於它不執行同步,所以速度更快。

java.lang.StringBuilder 一個可變的字元序列。此類提供一個與 StringBuffer 相容的 API,但不保證同步。該類被設計用作 StringBuffer 的一個簡易替換,用在字串緩衝區被單個線程使用的時候(這種情況很普遍)。如果可能,建議優先採用該類,因為在大多數實現中,它比 StringBuffer 要快。

在 StringBuilder 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類型的資料。每個方法都能有效地將給定的資料轉換成字串,然後將該字串的字元追加或插入到字串產生器中。 append 方法始終將這些字元添加到產生器的末端;而 insert 方法則在指定的點添加字元。

例如,如果 z 引用一個當前內容為“start”的字串產生器對象,則該方法調用 z.append("le") 將使字串產生器包含“startle”,而 z.insert(4, "le") 將更改字串產生器,使之包含“starlet”。

通 常,如果 sb 引用 StringBuilder 的執行個體,則 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。 每個字串產生器都有一定的容量。只要字串產生器所包含的字元序列的長度沒有超出此容量,就無需分配新的內部緩衝區。如果內部緩衝區溢位,則此容量自動 增大。

將 StringBuilder 的執行個體用於多個線程是不安全的。如果需要這樣的同步,則建議使用 StringBuffer。

使類和成員的可訪問能力最小化
複合優先於繼承
介面優先於抽象類別
如果字串特別長,採用charAt逐一擷取特定位置的字元是非常耗時的。因為每次擷取制定索引位置的字元都要引起新的檢索過程,更好的辦法是將字串通過調用toCharArray方法轉換成字元數組,然後通過數組索引值獲得指定位置的字元
使用移位操作來代替'a / b'操作 "/"是一個很“昂貴”的操作,使用移位操作將會更快更有效。
對於boolean值,避免不必要的等式判斷 將一個boolean值與一個true比較是一個恒等操作(直接返回該boolean變數的值). 移走對於boolean的不必要操作至少會帶來2個好處: 1)代碼執行的更快 (產生的位元組碼少了5個位元組); 2)代碼也會更加乾淨
盡量不要將大對象放到HttpSession或其他須序列化的對象中,並注意及時清空Session
引用《代碼大全》的一句話:
我得到了一個教訓,如果沒有測量效能變化,那麼你想當然的最佳化結果不過是代碼變得更為晦澀難懂了。如果你認為沒有必要通過測量來證實哪種方法更為有效,那麼同樣也沒有必要犧牲代碼可讀性,而把賭注押在效能的提高上。

不應該為想當然的效能改進而採用更晦澀的做法。
比如14樓的“使用移位操作來代替'a / b'操作 "/"是一個很“昂貴”的操作,使用移位操作將會更快更有效。”
首先是效能究竟損失了多少?
效能是不是在可以接受的範圍內?
更何況採用了想象的高效能方法,但最終的效能提升卻幾乎可以忽略不計。

對上面的操作我做了一下實驗:在10萬次運算中,可以轉化為移位操作的整數除運算耗時16毫秒。。有必要為此做代碼最佳化嗎?
代碼1:已耗用時間16毫秒
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
        long n = start / 2;
}
System.out.println(System.currentTimeMillis() - start);

代碼2:已耗用時間0
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
        long n = start >> 1;
}
System.out.println(System.currentTimeMillis() - start);

java中有很一些類是為同步而設定的。比如Hashtable,為了防止多個使用者同時訪問時出現問題進行了一些很好的設計。如果,你的資料可以被多個人 訪問,但是是一次寫入,然後基本上值有讀的操作,那就可以考慮不用它的同步機制,而是用HashMap等來代替它。而自己在適當的地方做些控制。(不是特 別推薦)
String / StringBuffer /StringBuilder,在字串串連操作上效能依次加強,我曾經做過一個實驗,連續進行10000次的字串操作,三者速度上的差距是驚人的。在 確切知道是不變字串的情況下,還是用String最好,因為Java語言中String採用了享元模式(Flyweight),在JVM中只存在一份相 同的String
用++i,代替i++

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.