Java數組/集合性能優化

1、 複製數組元素,使用System類arraycopy()方法替代循環賦值在數組之間複製元素

建議:System類arraycopy()方法複製數組元素
杜絕:循環賦值複製數組元素
原因: System類arraycopy()方法調用操作系統更底層函數,效率更高。
注:通過實測,在元素數量達到億級別,兩者都在幾百毫秒,都很快,System類arraycopy()比循環賦值性能僅快1倍,但仍推薦使用System類arraycopy()。

2、避免創建集合不設置初始容量

使用集合(List、Set、Map)存儲大量的對象
建議:先估計存儲的元素個數,然後在創建集合時設置集合的容量值要大於估計的元素個數。
杜絕:未設置集合容量值
原因:創建集合對象,如果未設置集合初始容量值,則使用默認值,而默認值都很小(如,ArrayList的初始容量爲10),一旦存儲的元素個數超過閾值,會造成集合擴容。擴容方式是根據擴容因子創建一個新的集合對象(初始容量=原有集合容量*擴容因子),再將原有集合中的元素拷貝到新的集合中。如果產生多次擴容,則會產生很多無用的中間集合對象,以及多次無意義的元素拷貝,性能低下。
正確示例: 估計存儲的元素個數最大爲10000,使用ArrayList集合

List list = new ArrayList(10000);

3、遍歷集合,使用迭代器替代循環調用帶索引的get方法

遍歷集合
建議:使用迭代器遍歷集合
杜絕:循環調用帶索引的get方法
原因:迭代器維護了遍歷集合的“指針”及內部狀態,它知道如何高效的遍歷集合。而集合提供的帶索引的get方法,對某些集合而言查找索引需要從第一個元素開始遍歷(如LinkedList),效率非常低下。
注:雖然迭代器遍歷某些特定集合性能並非最優,例如,遍歷ArrayList,使用循環調用帶索引的get方法就比迭代器性能略高一些,但是絕大多數情況下迭代器遍歷集合都是最優的。對LinkedList,帶索引的get方法要從第一個元素開始查找,使用循環調用帶索引的get方法遍歷效率非常低。
正確示例:

List list =…
Iterator it = list.iterator();
while(it.hasNext())
    {
        it.next()
    } 

錯誤示例:

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

4、單線程使用HashMap/ArrayList集合,避免使用HashTable/Vector

單線程使用集合
建議:HashMap/ArrayList
杜絕:HashTable/Vector
原因:HashMap/ArrayList是線程非安全的,元素的增加、刪除、查詢未實現同步,沒有鎖的申請和釋放開銷。而HashTable/Vector是線程安全的,元素的增加、刪除、查詢實現同步,存在鎖的申請和釋放開銷。

5、判斷元素是否在集合中存在,使用HashSet/HashMap替代List

判斷元素是否在集合中存在
建議:HashSet/HashMap
杜絕:List
原因:使用List集合存儲元素,則需要比較List集合中的所有元素,才能判斷查找的元素是否在集合中存在。
使用HashSet/HashMap存儲元素,HashSet/HashMap會將所有元素或Key按hash值分桶存儲。通過查找的元素或Key的hash值可快速找到其所在的桶,此步效率非常高(接近於數組的下標查找元素),然後只需比較桶上的元素即可判斷元素是否在集合存在,比較次數大大降低。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章