Mặc dù các câu trả lời đề xuất sử dụng ArrayList có ý nghĩa trong hầu hết các kịch bản, câu hỏi thực tế về hiệu suất tương đối chưa thực sự được trả lời.
Có một vài điều bạn có thể làm với một mảng:
- tạo ra nó
- đặt một mục
- lấy một món đồ
- sao chép / sao chép nó
Kết luận chung
Mặc dù các thao tác get và set có phần chậm hơn trên ArrayList (tương ứng 1 và 3 nano giây mỗi cuộc gọi trên máy của tôi), có rất ít chi phí sử dụng ArrayList so với mảng cho bất kỳ việc sử dụng không chuyên sâu nào. Tuy nhiên, có một số điều cần lưu ý:
- Thay đổi kích thước các hoạt động trong danh sách (khi gọi
list.add(...)
) rất tốn kém và người ta nên cố gắng đặt công suất ban đầu ở mức phù hợp khi có thể (lưu ý rằng vấn đề tương tự phát sinh khi sử dụng một mảng)
- khi giao dịch với người nguyên thủy, mảng có thể nhanh hơn đáng kể vì chúng sẽ cho phép người ta tránh được nhiều chuyển đổi đấm bốc / bỏ hộp
- một ứng dụng chỉ nhận / đặt các giá trị trong một ArrayList (không phổ biến lắm!) có thể thấy mức tăng hiệu suất hơn 25% bằng cách chuyển sang một mảng
Kết quả chi tiết
Dưới đây là kết quả tôi đo được cho ba thao tác đó bằng thư viện điểm chuẩn jmh (thời gian tính bằng nano giây) với JDK 7 trên máy tính để bàn x86 tiêu chuẩn. Lưu ý rằng ArrayList không bao giờ được thay đổi kích thước trong các thử nghiệm để đảm bảo kết quả có thể so sánh được. Mã điểm chuẩn có sẵn ở đây .
Tạo mảng / ArrayList
Tôi đã chạy 4 bài kiểm tra, thực hiện các tuyên bố sau:
- tạoArray1:
Integer[] array = new Integer[1];
- tạoList1:
List<Integer> list = new ArrayList<> (1);
- tạoArray10000:
Integer[] array = new Integer[10000];
- tạoList10000:
List<Integer> list = new ArrayList<> (10000);
Kết quả (tính bằng nano giây trên mỗi cuộc gọi, độ tin cậy 95%):
a.p.g.a.ArrayVsList.CreateArray1 [10.933, 11.097]
a.p.g.a.ArrayVsList.CreateList1 [10.799, 11.046]
a.p.g.a.ArrayVsList.CreateArray10000 [394.899, 404.034]
a.p.g.a.ArrayVsList.CreateList10000 [396.706, 401.266]
Kết luận: không có sự khác biệt đáng chú ý .
có được hoạt động
Tôi đã chạy 2 bài kiểm tra, thực hiện các tuyên bố sau:
- danh sách:
return list.get(0);
- getArray:
return array[0];
Kết quả (tính bằng nano giây trên mỗi cuộc gọi, độ tin cậy 95%):
a.p.g.a.ArrayVsList.getArray [2.958, 2.984]
a.p.g.a.ArrayVsList.getList [3.841, 3.874]
Kết luận: nhận được từ một mảng nhanh hơn khoảng 25% so với nhận được từ một ArrayList, mặc dù sự khác biệt chỉ theo thứ tự một nano giây.
thiết lập hoạt động
Tôi đã chạy 2 bài kiểm tra, thực hiện các tuyên bố sau:
- lập danh sách:
list.set(0, value);
- setArray:
array[0] = value;
Kết quả (tính bằng nano giây trên mỗi cuộc gọi):
a.p.g.a.ArrayVsList.setArray [4.201, 4.236]
a.p.g.a.ArrayVsList.setList [6.783, 6.877]
Kết luận: các thao tác thiết lập trên mảng nhanh hơn khoảng 40% so với danh sách, nhưng đối với get, mỗi thao tác thiết lập mất vài nano giây - do đó, để chênh lệch đạt 1 giây, người ta sẽ cần đặt các mục trong danh sách / mảng hàng trăm của hàng triệu lần!
bản sao / bản sao
Đại biểu copy constructor ArrayList để Arrays.copyOf
do đó hiệu suất giống hệt bản sao mảng (sao chép một mảng qua clone
, Arrays.copyOf
hoặc System.arrayCopy
làm cho không có sự khác biệt liệu hiệu suất-khôn ngoan ).