2012-11-21 35 views
6

Tôi đã đọc ở một vài nơi mà các vòng lặp chậm hơn lặp trên một mảng ... Mặc dù tôi hiểu rằng việc di chuyển về phía trước trong các khối sizeof (loại) thực tế là dễ dàng so với bất kỳ điều gì xảy ra phía sau để lặp lại chìa khóa của đối tượng, tôi vẫn còn tò mò, lý do chính xác là nó quá chậm ...Tại sao javascript chậm trong?

Có phải làm một hàm băm đảo ngược để lấy chìa khóa, và quá trình đó là chậm?

+2

Vâng, tôi đoán rằng nhận được tất cả các phím là một quá trình tương đối chậm so với ... không nhận được chúng;) 'for ... in' phải tra cứu các phím đầu tiên trong khi với một' for' bình thường vòng lặp, bạn đang cung cấp khóa thông qua biến vòng lặp. –

+2

Đây là một thử nghiệm JSPerf cho thấy chạy 'for ... in' gần như giống với' Object.keys() '(ít nhất là trong Chrome): http://jsperf.com/for-in- vs-keys-vs-for.Vì vậy, nhận được các phím và/hoặc tất cả mọi thứ liên quan đến điều này là chậm hơn và cung cấp các phím từ bên ngoài. Nhưng nó cũng phụ thuộc vào việc thực hiện, giống như T.J. nói. –

Trả lời

3

Câu trả lời thực sự cho điều này trong trường hợp của bất kỳ động cơ cụ thể nào sẽ phụ thuộc vào việc thực hiện của động cơ đó. (Như kích thước của sự khác biệt, nếu có.)

Tuy nhiên, có những bất biến. Ví dụ, hãy xem xét:

var obj = {a: "alpha", b: "beta"}; 
var name; 
for (name in obj) { 
    console.log(obj[name]); 
} 

var arr = ["alpha", "beta"]; 
var index; 
for (index = 0; index < arr.length; ++index) { 
    console.log(arr[index]); 
} 

Trong trường hợp của obj, động cơ có sử dụng một cơ chế để theo dõi trong đó thuộc tính bạn đã lặp lại và những người thân mà bạn chưa, cũng như lọc ra các thuộc tính không thể đếm được. Ví dụ: có một số loại đối tượng trình lặp đằng sau hậu trường (và cách xác định thông số, đó có thể là một mảng tạm thời).

Trong trường hợp arr, nó không; bạn đang xử lý điều đó trong mã của mình, theo cách rất đơn giản, hiệu quả.

Nội dung của khối của mỗi vòng lặp giống nhau: Tra cứu tài sản trên một đối tượng. (Trong trường hợp thứ hai, về mặt lý thuyết, cũng có chuyển đổi số thành chuỗi.)

Vì vậy, tôi hy vọng câu trả lời không thực hiện duy nhất cho điều này là: Chi phí bổ sung.

1

for..each vòng sử dụng iterators and generators.

Iterator là đối tượng có phương thức next(). Máy phát điện là chức năng của nhà máy có chứa các biểu thức yield(). Cả hai cấu trúc phức tạp hơn một biến chỉ số nguyên.

Trong vòng lặp for(var i = 0; i < arr.length; i++) điển hình, hai lệnh thực thi trong hầu hết các lần lặp lại là i++i < arr. Điều này được cho là nhanh hơn nhiều so với thực hiện một cuộc gọi chức năng (next() hoặc yield()).

Hơn nữa, việc bắt đầu vòng lặp (var i = 0) cũng nhanh hơn việc tạo đối tượng trình lặp với phương thức next() hoặc gọi trình tạo để tạo trình lặp. Tuy nhiên, nó phụ thuộc rất nhiều vào việc triển khai và những người sáng tạo công cụ Javascript làm hết sức mình để tăng tốc các tính năng ngôn ngữ thường được sử dụng như vậy.

Tôi có thể nói sự khác biệt quá nhỏ đến mức tôi có thể muốn dành thời gian tối ưu hóa các phần khác của mã. Việc lựa chọn cú pháp nên xem xét khả năng đọc mã và khả năng bảo trì nhiều hơn hiệu năng, khi hiệu suất đạt được quá nhỏ để tăng thêm độ phức tạp. Có nói rằng, sử dụng cú pháp có ý nghĩa hơn với bạn và các nhà phát triển khác, những người duy trì mã của bạn sau khi bạn trở nên giàu có và nổi tiếng! ;)