Động cơ hiện đại sẽ sử dụng mảng thực sau hậu trường ngay cả khi bạn sử dụng Array
nếu họ nghĩ rằng chúng có thể rơi xuống bản đồ thuộc tính "mảng" nếu bạn làm điều gì đó khiến họ nghĩ rằng họ không thể sử dụng đúng mảng.
Cũng lưu ý rằng như radsoc points out, var buffer = new ArrayBuffer(0x10000)
sau đó var Uint32 = new Uint32Array(buffer)
tạo ra một mảng uint32 có kích thước là 0x4000 (0x10000/4), không 0x10000, bởi vì giá trị mà bạn cung cấp cho ArrayBuffer
là tính theo byte, nhưng tất nhiên có bốn byte cho mỗi Uint32Array nhập . Tất cả những điều sau đây sử dụng new Uint32Array(0x10000)
thay vì (và luôn làm như vậy, ngay cả trước chỉnh sửa này) để so sánh táo với táo.
Vì vậy, hãy bắt đầu ở đó, với new Uint32Array(0x10000)
: http://jsperf.com/array-access-speed-2/11(buồn bã, JSPerf đã mất bài kiểm tra này và kết quả của nó, và bây giờ đang ẩn hoàn toàn)
Điều đó cho thấy rằng vì bạn' tái điền vào mảng theo một cách đơn giản, có thể dự đoán được, một động cơ hiện đại tiếp tục sử dụng một mảng thực (với lợi ích hiệu suất của chúng) dưới các bìa chứ không phải chuyển dịch. Chúng tôi nhìn thấy cơ bản cùng một hiệu suất cho cả hai. Sự khác biệt về tốc độ có thể liên quan đến chuyển đổi loại có giá trị Uint32
và gán nó cho sum
làm number
(mặc dù tôi ngạc nhiên nếu chuyển đổi loại đó không bị trì hoãn ...).
Thêm một số hỗn loạn, mặc dù:
var Uint32 = new Uint32Array(0x10000);
var arr = [];
for (var i = 0x10000 - 1; i >= 0; --i) {
Uint32[Math.random() * 0x10000 | 0] = (Math.random() * 0x100000000) | 0;
arr[Math.random() * 0x10000 | 0] = (Math.random() * 0x100000000) | 0;
}
var sum = 0;
... để động cơ đã rơi trở lại trên bản đồ bất động sản kiểu cũ "mảng", và bạn thấy rằng mảng đánh máy rõ rệt làm tốt hơn cái cũ lỗi thời loại: http://jsperf.com/array-access-speed-2/3(buồn bã, JSPerf đã mất bài kiểm tra này và kết quả của nó)
Clever, những JavaSc kỹ sư động cơ ript ...
Điều cụ thể bạn làm với bản chất không phải mảng của các vấn đề mảng Array
, mặc dù; xem xét:
var Uint32 = new Uint32Array(0x10000);
var arr = [];
arr.foo = "bar"; // <== Non-element property
for (var i = 0; i < 0x10000; ++i) {
Uint32[i] = (Math.random() * 0x100000000) | 0;
arr[i] = (Math.random() * 0x100000000) | 0;
}
var sum = 0;
Điều đó vẫn lấp đầy mảng dự đoán, nhưng chúng tôi thêm thuộc tính không phải là phần tử (foo
) vào đó. http://jsperf.com/array-access-speed-2/4(buồn bã, JSPerf đã mất bài kiểm tra này và kết quả của nó) Rõ ràng, động cơ là khá thông minh, và giữ cho rằng tài sản phi yếu tố sang một bên trong khi tiếp tục sử dụng một mảng đúng đối với các thuộc tính nguyên tố:
Tôi đang mất một chút để giải thích tại sao mảng chuẩn nên nhận được nhanh hơn ở đó so với thử nghiệm đầu tiên ở trên. Lỗi đo lường? Âm đạo trong Math.random
? Nhưng chúng tôi vẫn khá chắc chắn rằng dữ liệu mảng cụ thể trong các Array
vẫn là một mảng thực sự.
Trong khi đó, nếu chúng ta làm điều tương tự nhưng điền theo thứ tự ngược:
var Uint32 = new Uint32Array(0x10000);
var arr = [];
arr.foo = "bar"; // <== Non-element property
for (var i = 0x10000 - 1; i >= 0; --i) { // <== Reverse order
Uint32[i] = (Math.random() * 0x100000000) | 0;
arr[i] = (Math.random() * 0x100000000) | 0;
}
var sum = 0;
... chúng tôi lấy lại cho mảng gõ thắng ra — trừ trên IE11: http://jsperf.com/array-access-speed-2/9(buồn bã, JSPerf có mất bài kiểm tra này và kết quả của nó)
Bạn có xóa các kiểm tra jsperf không? Tôi không thể truy cập chúng nữa – Bergi
Không, tôi đã không xóa nó. Điều này thật kỳ lạ. –
Rất, rất lạ là chúng sẽ biến mất như thế! Tất cả trong số họ ... Đặc biệt kỳ lạ trong ánh sáng của [mục FAQ này] (http://jsperf.com/faq#test-availability). Tôi đã tìm kiếm trong trường hợp URL thay đổi hoặc một cái gì đó, và ... không có gì. Tôi có thể tìm thấy các xét nghiệm khác về hiệu suất mảng, nhưng không phải của Sukhanov và của tôi. Tôi đã nêu ra [vấn đề cho nó] (https://github.com/mathiasbynens/jsperf.com/issues/197). Tất nhiên, nó có thể sẽ không làm tổn thương nếu nhiều người trong chúng ta [quyên góp cho jsPerf] (http://jsperf.com/faq#donate) (và tôi đã làm ... lần đầu tiên * đầu vịt *). –