Ngược lại, phiên bản nhanh nhất, trên Hotspot 8, là:
MyClass[] arr = myList.toArray(new MyClass[0]);
Tôi đã chạy một điểm chuẩn vi mô bằng cách sử dụng jmh các kết quả và mã bên dưới, cho thấy phiên bản có mảng trống luôn vượt trội so với phiên bản có mảng được chỉ định. Lưu ý rằng nếu bạn có thể sử dụng lại một mảng hiện có kích thước chính xác, kết quả có thể khác.
Kết quả điểm chuẩn (điểm tính bằng micrô giây, nhỏ hơn = tốt hơn):
Benchmark (n) Mode Samples Score Error Units
c.a.p.SO29378922.preSize 1 avgt 30 0.025 ▒ 0.001 us/op
c.a.p.SO29378922.preSize 100 avgt 30 0.155 ▒ 0.004 us/op
c.a.p.SO29378922.preSize 1000 avgt 30 1.512 ▒ 0.031 us/op
c.a.p.SO29378922.preSize 5000 avgt 30 6.884 ▒ 0.130 us/op
c.a.p.SO29378922.preSize 10000 avgt 30 13.147 ▒ 0.199 us/op
c.a.p.SO29378922.preSize 100000 avgt 30 159.977 ▒ 5.292 us/op
c.a.p.SO29378922.resize 1 avgt 30 0.019 ▒ 0.000 us/op
c.a.p.SO29378922.resize 100 avgt 30 0.133 ▒ 0.003 us/op
c.a.p.SO29378922.resize 1000 avgt 30 1.075 ▒ 0.022 us/op
c.a.p.SO29378922.resize 5000 avgt 30 5.318 ▒ 0.121 us/op
c.a.p.SO29378922.resize 10000 avgt 30 10.652 ▒ 0.227 us/op
c.a.p.SO29378922.resize 100000 avgt 30 139.692 ▒ 8.957 us/op
Để tham khảo, mã:
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
public class SO29378922 {
@Param({"1", "100", "1000", "5000", "10000", "100000"}) int n;
private final List<Integer> list = new ArrayList<>();
@Setup public void populateList() {
for (int i = 0; i < n; i++) list.add(0);
}
@Benchmark public Integer[] preSize() {
return list.toArray(new Integer[n]);
}
@Benchmark public Integer[] resize() {
return list.toArray(new Integer[0]);
}
}
Bạn có thể tìm thấy kết quả tương tự, phân tích đầy đủ và thảo luận trong bài đăng trên blog Mảng về trí tuệ của người xưa . Tóm lại: trình biên dịch JVM và JIT chứa một số tối ưu hóa cho phép nó tạo và khởi tạo một mảng có kích thước chính xác mới và không thể sử dụng các tối ưu hóa đó nếu bạn tự tạo mảng.