TL; DR : List.stream().forEach()
là nhanh nhất.
Tôi cảm thấy tôi nên thêm kết quả của mình từ việc lặp lại điểm chuẩn. Tôi đã thực hiện một cách tiếp cận rất đơn giản (không có khung điểm chuẩn) và điểm chuẩn 5 phương pháp khác nhau:
- cổ điển
for
- foreach cổ điển
List.forEach()
List.stream().forEach()
List.parallelStream().forEach
quy trình và thông số kiểm tra
private List<Integer> list;
private final int size = 1_000_000;
public MyClass(){
list = new ArrayList<>();
Random rand = new Random();
for (int i = 0; i < size; ++i) {
list.add(rand.nextInt(size * 50));
}
}
private void doIt(Integer i) {
i *= 2; //so it won't get JITed out
}
Danh sách trong lớp này sẽ được lặp đi lặp lại và có một số doIt(Integer i)
áp dụng cho tất cả các thành viên của nó, mỗi lần thông qua một phương thức khác nhau. trong lớp Main, tôi chạy phương thức được thử nghiệm ba lần để làm nóng JVM. Sau đó tôi chạy phương thức kiểm tra 1000 lần tổng hợp thời gian cần thiết cho mỗi phương pháp lặp (sử dụng System.nanoTime()
). Sau khi xong, tôi chia số tiền đó cho 1000 và đó là kết quả, thời gian trung bình. thí dụ:
myClass.fored();
myClass.fored();
myClass.fored();
for (int i = 0; i < reps; ++i) {
begin = System.nanoTime();
myClass.fored();
end = System.nanoTime();
nanoSum += end - begin;
}
System.out.println(nanoSum / reps);
Tôi đã chạy nó trên CPU i5 4 nhân, với phiên bản java 1.8.0_05
cổ điển for
for(int i = 0, l = list.size(); i < l; ++i) {
doIt(list.get(i));
}
thời gian thực hiện: 4,21 ms
foreach cổ điển
for(Integer i : list) {
doIt(i);
}
thời gian thực hiện: 5,95 ms
List.forEach()
list.forEach((i) -> doIt(i));
thời gian thực hiện: 3,11 ms
List.stream().forEach()
list.stream().forEach((i) -> doIt(i));
thời gian thực hiện: 2,79 ms
List.parallelStream().forEach
list.parallelStream().forEach((i) -> doIt(i));
thời gian thực hiện: 3,6 ms