Tôi nghĩ rằng tôi đã hiểu sự khác biệt giữa ArrayList và LinkedList về mặt lý thuyết khá tốt. Tuy nhiên, đây là lần đầu tiên tôi đưa nó vào một bài kiểm tra nhỏ, và các bài kiểm tra xuất hiện, khác với những kỳ vọng của tôi.Sự khác biệt giữa ArrayList và LinkedList trong Java - whys cho hiệu suất
vọng:
ArrayList sẽ chậm hơn so LinkedList khi chèn vào đầu, vì nó có để "thay đổi" các yếu tố, cho linkedlist, chỉ cập nhật tài liệu tham khảo 2 của nó.
Thực tế: xuất hiện giống nhau trên hầu hết các lần lặp lại. Đối với một số lựa chọn số lặp lại, nó sẽ chậm hơn.
Danh sách sẽ chậm hơn LinkedList khi xóa lúc đầu, vì nó phải "dịch chuyển" các phần tử, cho Danh sách liên kết, nó chỉ hủy một phần tử.
Thực tế: Hiệu suất giống nhau khi xóa khỏi cầu xin.
Test Case: 1.000.000 yếu tố
public static void main(String[] args) {
int n = 1000000;
List arrayList = new ArrayList(n+10);
long milis = System.currentTimeMillis();
for(int i= 0 ;i<n;i++){
arrayList.add(i);
}
System.out.println("insert arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
List linkedList = new LinkedList();
milis = System.currentTimeMillis();
for(int i= 0 ;i<n;i++){
linkedList.add(i);
}
System.out.println("insert linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
//System.out.println("Adding at end");
milis = System.currentTimeMillis();
arrayList.add(n-5,n+1);
System.out.println("APPEND arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.add(n-5,n+1);
System.out.println("APPEND linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
//add at front
milis = System.currentTimeMillis();
arrayList.add(0,0);
System.out.println("INSERT BEG arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.add(0,0);
System.out.println("INSERT BEG linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
//add at middle
milis = System.currentTimeMillis();
arrayList.add(n/2,n/2);
System.out.println("INSERT MIDDLE arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.add(n/2,n/2);
System.out.println("INSERT MIDDLE linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
//get from front, mid, end
milis = System.currentTimeMillis();
arrayList.get(0);
System.out.println("get front arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.get(0);
System.out.println("get front linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
arrayList.get(n/2);
System.out.println("get MIDDLE arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.get(n/2);
System.out.println("get MIDDLE linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
arrayList.get(n-4);
System.out.println("get last arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.get(n-4);
System.out.println("get last linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
//delete from front, mid, end.
milis = System.currentTimeMillis();
arrayList.remove(0);
System.out.println("del front arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.remove(0);
System.out.println("del front linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
arrayList.remove(n/2);
System.out.println("del mid arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.remove(n/2);
System.out.println("del mid linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
arrayList.remove(n-4);
System.out.println("del end arraylist takes "+(System.currentTimeMillis()-milis)+" ms");
milis = System.currentTimeMillis();
linkedList.remove(n-4);
System.out.println("del end linkedlist takes "+(System.currentTimeMillis()-milis)+" ms");
}
Output Log
insert arraylist takes 141 ms
insert linkedlist takes 312 ms
APPEND arraylist takes 0 ms
APPEND linkedlist takes 0 ms
INSERT BEG arraylist takes 0 ms
INSERT BEG linkedlist takes 0 ms
INSERT MIDDLE arraylist takes 0 ms
INSERT MIDDLE linkedlist takes 0 ms
get front arraylist takes 0 ms
get front linkedlist takes 0 ms
get MIDDLE arraylist takes 0 ms
get MIDDLE linkedlist takes 16 ms
get last arraylist takes 0 ms
get last linkedlist takes 0 ms
del front arraylist takes 0 ms
del front linkedlist takes 0 ms
del mid arraylist takes 0 ms
del mid linkedlist takes 15 ms
del end arraylist takes 0 ms
del end linkedlist takes 0 ms
Vì vậy, lý do là gì? JDK 1.6 được sử dụng.
EDIT: Sau khi sử dụng System.nanotime(), nó đã cho tôi câu trả lời như tôi mong đợi. Đồng ý, chỉ một thử nghiệm duy nhất của nó và phải được tính trung bình.
insert arraylist takes 137076082 ns
insert linkdlist takes 318985917 ns
APPEND arraylist takes 69751 ns
APPEND linkdlist takes 98126 ns
**INSERT BEG arraylist takes 2027764 ns
INSERT BEG linkdlist takes 53522 ns**
INSERT MIDDLE arraylist takes 1008253 ns
INSERT MIDDLE linkdlist takes 10395846 ns
get front arraylist takes 42364 ns
get front linkdlist takes 77473 ns
get MIDDLE arraylist takes 39499 ns
get MIDDLE linkdlist takes 9645996 ns
get last arraylist takes 46165 ns
get last linkdlist takes 43446 ns
**del front arraylist takes 1720329 ns
del front linkdlist takes 108063 ns**
del mid arraylist takes 1157398 ns
del mid linkdlist takes 11845077 ns
del end arraylist takes 54149 ns
del end linkdlist takes 49744 ns
khi thực hiện đo điểm chuẩn micro, luôn luôn sử dụng 'System.nanoTime()' – Nishant
Tôi tự hỏi bao nhiêu thời gian autoboxing int mất trong trường hợp của bạn, trên pass đầu tiên của bạn, bạn sẽ được điền Integers cache –
Đồng ý với @Nishant ở trên. 0ms cho hầu hết các thử nghiệm không hữu ích. Thời gian thực có thể là 50nanoseconds và 300nanoseconds. – mtariq