ArrayList和LinkedList都繼承自List, 內在實現機制有所不同,關於區別方面已經有很多優秀的文章進行了介紹。本文從實踐角度出發,對比兩種List在不同操作中的性能,便於讀者在特定場景中參考選型。由於電腦配置,JDK版本,IDE等會導致測試結果又出入甚至有結論不太一致的結果,本文的試驗結果僅具備一定的參考價值。
一 插入數據
以同樣的方式向兩種List中插入數據,首先插入簡單類型數據,這裏插入簡單字符串。表中數據以毫秒爲單位,不到1毫秒的近似爲1毫秒。
/**
* add element for List
* @param sourceArray source element array
* @param list list to add element
*/
public void setEleForList(Object[] sourceArray, List list){
int len = sourceArray.length;
for (int i = 0; i < len; i++){
list.add(sourceArray[i]);
}
}
操作條數 | ArrayList | LinkedList |
---|---|---|
1000 | 6 | 1 |
10000 | 13 | 1 |
100000 | 10 | 19 |
1000000 | 24 | 45 |
1000000 | 347 | 939 |
表中的數據時間單位都是毫秒。明顯可見,在數量較少的情況下,LinkedList有絕對的速度優勢,超過100000條以上,ArrayList就佔據了明顯的優勢。
二 讀取List數據
查找數據是容器的一項重要操作,通常而言取數據要比存入和修改來得更頻繁。在遍歷列表方面,二者對比如何呢。這裏採用兩種讀取的方式,一種是順序讀取,一種是隨機選擇。
/**
* iterate through list
*
* @param list list to iterate through
*/
public void getAllEleFromList(List list){
int size = list.size();
for (int i = 0; i < size; i++){
Object object = list.get(i);
}
}
操作條數 | ArrayList | LinkedList |
---|---|---|
1000 | 1 | 2 |
10000 | 1 | 34 |
100000 | 2 | 5435 |
/**
* get random elements form list
*
* @param list list to get from
* @param num number of elements to get
*/
public void getRandomEleFromList(List list,int num){
int size = list.size();
Random random = new Random();
for (int i = 0; i < num; i++){
Object object = list.get(random.nextInt(size - 1));
}
}
操作條數 | ArrayList | LinkedList |
---|---|---|
1000 | 1 | 1 |
10000 | 3 | 40 |
100000 | 6 |
6420 |
List的順序遍歷有多重方式,二者統一採取了按下標遞增遍歷的方式進行。隨機讀取的次數和列表的長度相同,在測試時間上需要加上產生隨機數的時間。鑑於二者在十萬條數據上差別已經巨大,不再繼續測試。
三 刪除List數據
對List的刪除操作是容易產生異常的地方,日常操作時要格外小心。這裏隨機對列表已有元素進行刪除。刪除的數量爲列表長度的十分之一。
/**
* remove random number elements form list
*
* @param list list to remove
* @param num number to remove
*/
public void removeEleFromList(List list, int num){
int size = list.size();
Random random = new Random();
for (int i = 0; i < num; i++){
Object object = list.remove(random.nextInt(size - 1 - i));
}
}
操作條數 | ArrayList | LinkedList |
---|---|---|
1000 | 1 | 1 |
10000 | 2 | 8 |
100000 | 45 | 893 |
1000000 | 6261 | 73234 |
可見,和插入、查詢相比,List的刪除是最耗時間的操作也最容易出問題。
四 清除List數據
有建立,就有銷燬,如果銷燬List採用上面逐個刪除的方式,那這個時間代價是不能接受的。系統採用的清除List的方式要簡便快速許多,這裏就不貼系統代碼了,直接看時間對比。
操作條數 | ArrayList | LinkedList |
---|---|---|
1000 | 1 | 1 |
10000 | 1 | 1 |
100000 | 1 | 3 |
1000000 | 3 | 6 |
1000000 | 11 | 42 |
總結
通過測試數據可得,在大部分場景下,ArrayList是優於LinkedList的,只有在少量數據插入時,LinkedList有一定優勢。
本文對List的重要操作性能進行了對比,List接口還有很多實現方法,感興趣的話可以自己親手實踐。
理論要聯繫實際,從實踐中總結理論。造成測試結果的原因是多方面的,不僅僅依賴接口的實現,與參數類型,操作系統,虛擬機都可能有關,後面我們會從源碼的角度解讀測試結果。