這麼多的List 實現,如何選擇?他們的運行效率具體怎樣?本篇文章將用具體的代碼來檢測其中最最常用的一些List 實現
主要測試對象:
java.util.ArrayList;
java.util.LinkedList;
java.util.Stack;
java.util.Vector;
java.util.concurrent.CopyOnWriteArrayList;
org.apache.commons.collections.FastArrayList;
org.apache.commons.collections.list.TreeList;
測試用例:
1.測試List
1.1順序添加
1.2隨機插入
1.3隨機刪除
1.4隨機訪問
1.5隨機更新
1.5順序迭代
1.6for順序迭代
2.測試List 在三種情況下的排序效率
2.1初始時List 中元素已從小到大有序排列(最優情況)
2.2初始時List 中元素已從大到小有序排列(最差情況)
2.3初始時List 中元素隨機排列,無序
3.測試List 互相轉換的效率
3.1轉化爲TreeList
3.2轉化爲ArrayList
3.3轉化爲LinkedList
3.4轉化爲CopyOnWriteArrayList
3.5轉化爲Vector
測試代碼:
- import static java.lang.System.out;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Iterator;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Stack;
- import java.util.Vector;
- import java.util.concurrent.CopyOnWriteArrayList;
- import org.apache.commons.collections.FastArrayList;
- import org.apache.commons.collections.list.TreeList;
- import org.apache.commons.lang.StringUtils;
- import org.apache.commons.lang.time.StopWatch;
- @SuppressWarnings("unchecked")
- public class ListPerformance {
- public static void main(String[] args) {
- ListPerformance test = new ListPerformance(10 * 10000);
- out.print(StringUtils.center("Test List Performance: loop=" + test.loop, 80, '-'));
- out.printf("\n ssssssss", "", "add", "insert", "remove", "get", "set",
- "iterator","for");
- test.benchmark(new FastArrayList());
- test.benchmark(new TreeList());
- test.benchmark(new ArrayList());
- test.benchmark(new LinkedList());
- test.benchmark(new CopyOnWriteArrayList());
- test.benchmark(new Vector());
- test.benchmark(new Stack());
- //2.測試排序
- out.print("\n\n");
- out.print(StringUtils.center("Test List sort Performance: loop=" + test.loop, 80, '-'));
- out.printf("\n ssss", "", "optimize", "worst", "random");
- test.benchmarkSort(new FastArrayList());
- test.benchmarkSort(new TreeList());
- test.benchmarkSort(new ArrayList());
- test.benchmarkSort(new LinkedList());
- //test.benchmarkSort(new CopyOnWriteArrayList());//UnsupportedOperationException
- test.benchmarkSort(new Vector());
- test.benchmarkSort(new Stack());
- //3.測試各種數據結構間轉化
- out.print("\n\n");
- out.print(StringUtils.center("Test List convert Performance: loop=" + test.loop, 80, '-'));
- out.printf("\n ssssss", "", "Tree", "Array", "Linked", "CopyOnWrite",
- "Vector");
- test.benchmarkConvert(new FastArrayList());
- test.benchmarkConvert(new TreeList());
- test.benchmarkConvert(new ArrayList());
- test.benchmarkConvert(new LinkedList());
- test.benchmarkConvert(new CopyOnWriteArrayList());
- }
- private int loop = 10000;
- public ListPerformance(int loop) {
- this.loop = loop;
- }
- public void benchmark(List list) {
- out.printf("\n s", list.getClass().getSimpleName());
- int j;
- StopWatch watch = null;
- //1.測試順序性能(Add)
- (watch = new StopWatch()).start();
- for (int i = 0; i < loop; i++) {
- list.add(new Integer(i));
- }
- watch.stop();
- out.printf("d", watch.getTime());
- //2.測試隨機插入性能(Random insert)
- (watch = new StopWatch()).start();
- for (int i = 0; i < loop; i++) {
- j = (int) (Math.random() * loop);
- list.add(j, new Integer(-j));
- }
- watch.stop();
- out.printf("d", watch.getTime());
- //3.測試隨機索引刪除(Random remove)
- (watch = new StopWatch()).start();
- for (int i = 0; i < loop; i++) {
- j = (int) (Math.random() * loop);
- list.remove(j);
- }
- watch.stop();
- out.printf("d", watch.getTime());
- //4.測試隨機取數性能(Random get)
- (watch = new StopWatch()).start();
- for (int i = 0; i < loop; i++) {
- j = (int) (Math.random() * loop);
- list.get(j);
- }
- watch.stop();
- out.printf("d", watch.getTime());
- //5.測試隨機更新性能(Random set)
- (watch = new StopWatch()).start();
- for (int i = 0; i < loop; i++) {
- j = (int) (Math.random() * loop);
- list.set(j, j);
- }
- watch.stop();
- out.printf("d", watch.getTime());
- //6.測試迭代性能(Iterator)
- (watch = new StopWatch()).start();
- Iterator<Object> iter = list.iterator();
- while (iter.hasNext()) {
- iter.next();
- }
- watch.stop();
- out.printf("d", watch.getTime());
- //7.測試迭代性能(Iterator)
- (watch = new StopWatch()).start();
- // Iterator<Object> iter = list.iterator();
- for (Object obj : list) {
- }
- watch.stop();
- out.printf("d", watch.getTime());
- }
- public void benchmarkConvert(List list) {
- out.printf("\n s", list.getClass().getSimpleName());
- StopWatch watch = null;
- //1.轉TreeList
- (watch = new StopWatch()).start();
- new TreeList(list);
- watch.stop();
- out.printf("d", watch.getTime());
- //2.轉ArrayList
- (watch = new StopWatch()).start();
- new ArrayList(list);
- watch.stop();
- out.printf("d", watch.getTime());
- //3.轉LinkedList
- (watch = new StopWatch()).start();
- new LinkedList(list);
- watch.stop();
- out.printf("d", watch.getTime());
- //4.轉CopyOnWriteArrayList
- (watch = new StopWatch()).start();
- new CopyOnWriteArrayList(list);
- watch.stop();
- out.printf("d", watch.getTime());
- //5.轉Vector
- (watch = new StopWatch()).start();
- new Vector(list);
- watch.stop();
- out.printf("d", watch.getTime());
- }
- public void benchmarkSort(List list) {
- out.printf("\n s", list.getClass().getSimpleName());
- StopWatch watch = null;
- //1.順序List
- for (int i = 0; i < loop; i++) {
- list.add(new Integer(i));
- }
- (watch = new StopWatch()).start();
- Collections.sort(list);
- watch.stop();
- out.printf("d", watch.getTime());
- //2.逆序List
- for (int i = loop - 1; i > 0; i--) {
- list.add(new Integer(i));
- }
- (watch = new StopWatch()).start();
- Collections.sort(list);
- watch.stop();
- out.printf("d", watch.getTime());
- //3.隨機順序List
- for (int i = 0, j = 0; i < loop; i++) {
- j = (int) (Math.random() * loop);
- list.add(new Integer(j));
- }
- (watch = new StopWatch()).start();
- Collections.sort(list);
- watch.stop();
- out.printf("d", watch.getTime());
- }
- }
測試結果:
-----------------------Test List Performance: loop=100000-----------------------
add insert remove get set iterator for
FastArrayList 31 16344 16312 47 62 0 0
TreeList 156 391 281 109 110 15 0
ArrayList 47 16406 16500 16 47 16 0
LinkedList 15 149719 264203 176125 179406 0 31
CopyOnWriteArrayList 27422 141797 160906 31 65375 0 0
Vector 16 26391 24437 31 47 16 0
Stack 31 25094 22703 31 16 16 0
--------------------Test List sort Performance: loop=100000---------------------
optimize worst random
FastArrayList 31 78 188
TreeList 32 94 343
ArrayList 16 94 172
LinkedList 16 266 219
Vector 15 78 219
Stack 15 94 156
-------------------Test List convert Performance: loop=100000-------------------
Tree Array LinkedCopyOnWrite Vector
FastArrayList 0 0 0 0 0
TreeList 0 0 0 0 0
ArrayList 0 0 0 0 0
LinkedList 0 0 0 0 0
CopyOnWriteArrayList 0 0 0 0 0
結論:
1.隨機插入、隨機刪除操作中,用TreeList 效率最高;
2.在只需要追加、迭代的環境下,LinkedList 效率最高;
3.平均效率來講,ArrayList 相對平衡,但如果海量隨機操作,還是會造成性能瓶頸;
4.CopyOnWriteArrayList 因爲線程安全的原因,致使性能降低很多,所以慎用;
5.Vector 沒有傳說中那麼低的效率;
6.讓Stack 來做List 的事可以,不過語義上Stack 不應該做過多的List 的事情;
7.在排序中,ArrayList 具有最好的性能,TreeList 平均性能也不錯,LinkedList 的排序效率受元素初始狀態的影響很大。
8.各種List 間轉換幾乎沒有時間損耗。
注:增強性for循環其實是對iterator循環的一種簡單寫法,在編譯時增強性for循環會被編譯爲iterator的for循環寫法。在測試結果中兩者變現出來的性能有一點相差(不正確,有時變現的快,有時變現的慢一點,可能與其他因素有關係),從理論上說,應該基本一樣。
引用地址:http://ldbjakyo.iteye.com/blog/1142899
http://blog.sina.com.cn