Tiêu đề liên quan đến Tại sao xử lý mảng được sắp xếp nhanh hơn mảng không được sắp xếp?
Đây cũng là một hiệu ứng dự đoán nhánh phải không? Hãy lưu ý: ở đây quá trình xử lý cho mảng đã sắp xếp chậm hơn !!
Hãy xem xét đoạn mã sau:
private static final int LIST_LENGTH = 1000 * 1000;
private static final long SLOW_ITERATION_MILLIS = 1000L * 10L;
@Test
public void testBinarySearch() {
Random r = new Random(0);
List<Double> list = new ArrayList<>(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) {
list.add(r.nextDouble());
}
//Collections.sort(list);
// remove possible artifacts due to the sorting call
// and rebuild the list from scratch:
list = new ArrayList<>(list);
int nIterations = 0;
long startTime = System.currentTimeMillis();
do {
int index = r.nextInt(LIST_LENGTH);
assertEquals(index, list.indexOf(list.get(index)));
nIterations++;
} while (System.currentTimeMillis() < startTime + SLOW_ITERATION_MILLIS);
long duration = System.currentTimeMillis() - startTime;
double slowFindsPerSec = (double) nIterations / duration * 1000;
System.out.println(slowFindsPerSec);
...
}
Điều này in ra giá trị khoảng 720 trên máy của tôi.
Bây giờ nếu tôi kích hoạt lệnh gọi sắp xếp bộ sưu tập, giá trị đó sẽ giảm xuống 142. Tại sao?!?
Kết quả là kết luận, chúng không thay đổi nếu tôi tăng số lần lặp / lần.
Phiên bản Java là 1.8.0_71 (Oracle VM, 64 bit), chạy trên Windows 10, thử nghiệm JUnit trong Eclipse Mars.
CẬP NHẬT
Có vẻ như liên quan đến truy cập bộ nhớ liền kề (Đối tượng kép được truy cập theo thứ tự tuần tự so với thứ tự ngẫu nhiên). Hiệu ứng bắt đầu biến mất đối với tôi đối với độ dài mảng khoảng 10k trở xuống.
Cảm ơn assylias đã cung cấp kết quả :
/**
* Benchmark Mode Cnt Score Error Units
* SO35018999.shuffled avgt 10 8.895 ± 1.534 ms/op
* SO35018999.sorted avgt 10 8.093 ± 3.093 ms/op
* SO35018999.sorted_contiguous avgt 10 1.665 ± 0.397 ms/op
* SO35018999.unsorted avgt 10 2.700 ± 0.302 ms/op
*/