2012-03-30 38 views
11

Trong trang web this có danh sách các biến thể vòng lặp. Tôi có thể hiểu cách sử dụng vòng lặp for(var i=0, len=arr.length; i<len ;i++) (trong đó arr là một mảng), vì arr.length không được tính trong mỗi bước có vẻ là một hiệu suất cận biên. Tuy nhiên, lợi thế của việc sử dụng các biến thể khác là gì? Ví dụ, vòng nhưĐối với các biến thể vòng lặp trong javascript

  1. for (var i=arr.length; i--;)
  2. for (var i=0, each; each = arr[i]; i++)

Có bất kỳ thay đổi đáng chú ý trong hoạt động bằng cách sử dụng khác nhau cho các biến vòng lặp? Tôi thường sử dụng for(var i=0, len=arr.length; i<len ;i++) ngay cả đối với mảng rất lớn. Vì vậy, tôi chỉ muốn biết nếu có điều gì đó tôi đang bỏ lỡ ở đây.

+0

vòng lặp "giảm tốc" nhanh hơn nhiều trong js. như đối với người cuối cùng tôi sẽ không sử dụng nó, vì trong js false == 0 == "". – mpm

+0

bản sao có thể có của [JavaScript - Các vòng lặp thực sự có đảo ngược nhanh hơn không ...?] (Http://stackoverflow.com/questions/1340589/javascript-are-loops-really-faster-in-reverse) – Matt

+1

@camus người ta có thể hữu ích khi lặp qua ví dụ. một tập hợp các phần tử DOM. –

Trả lời

6

Nó được coi là rộng rãi rằng một đảo ngược trong khi vòng lặp

var loop = arr.length; 
while(loop--) { 
} 

là loop-type nhanh nhất có sẵn trong ngôn ngữ C-like (điều này cũng áp dụng cho ECMAScript cho khá trong một, nhưng tôi nghĩ rằng tất cả các up-to -date động cơ là khá ngay cả trên các vòng tiêu chuẩn ngày hôm nay). (jsperf)

'Biến thể' của bạn thực sự không có biến thể, nhưng chỉ sử dụng câu lệnh conditional khác nhau trong phạm vi for-loop (mà thực sự biến nó thành biến thể..doh!). Giống như

1) for (var i=arr.length; i--;)

Chỉ cần sử dụng một phần có điều kiện từ for-loop để làm cả hai, đi làm lại và kiểm tra nếu i có một giá trị truthy. Ngay sau khi i trở thành 0 vòng lặp sẽ kết thúc.

2) for (var i=0, each; each = arr[i]; i++)

Ở đây chúng ta có được các yếu tố từ mỗi lần lặp, vì vậy chúng ta có thể truy cập trực tiếp mà bên trong thân vòng lặp. Điều này thường được sử dụng khi bạn mệt mỏi vì luôn lặp lại arr[ n ].

Bạn đang làm việc tốt trong bộ nhớ đệm thuộc tính .length trước khi lặp. Như bạn đã đề cập một cách chính xác, nó nhanh hơn vì chúng ta không phải truy cập thuộc tính đó trong mỗi lần lặp lại. Ngoài ra, đôi khi nó cũng được yêu cầu trong kịch bản DOM, khi xử lý 'cấu trúc trực tiếp' như HTMLCollections.

2

Vấn đề là khi bạn giảm dần trình lặp, bạn thực sự so sánh nó với 0 thay vì độ dài, nhanh hơn vì các toán tử "<, < =,>,> =" yêu cầu kiểm tra kiểu trên cả hai bên trái và bên phải của toán tử để xác định hành vi so sánh nào nên được sử dụng.

vòng nhanh nhất là: (Nếu bạn không quan tâm đến thứ tự tất nhiên)

var i = arr.length 
while(i--) 
{ 
} 

Nếu bạn quan tâm đến trình tự, phương pháp mà bạn đang sử dụng là tốt.

1

Đây là cách sử dụng kém của mỗi vòng lặp vì nó sẽ thất bại trên các giá trị giả, phá vỡ vòng lặp.

for (var i=0, each; each = arr[i]; i++) 

Tôi cũng sẽ không sử dụng vòng lặp này (thậm chí khó khăn có thể nhanh hơn ...)

for (var i=arr.length; i--;) 

Có vẻ khó hiểu và ít dễ đọc hơn, bạn cũng có thể viết ngược lại trong khi lặp lại.

2

Theo jsperf loại nhanh nhất của vòng lặp trong JavaScript là

var arr = new Array(10); 
var i = 0; 
while (i < arr.length) { 
arr[i]; 
i++; 
}; 

ngay trước (loop mặc định của tôi)

var arr = new Array(10); 
for (var i = 0; i < arr.length; ++i) { 
arr[i]; 
}; 

Với điều này là chậm nhất:

var arr = new Array(10); 
arr.forEach(function(x) { 
x; 
}); 

ít nhất là trên Chrome 17 trên OSX 10.7.3. Vì vậy, có vẻ như vòng lặp "mặc định" là tốt sau khi tất cả!

+0

Các kiểm tra jsperf này rất hữu ích. Cảm ơn bạn! –

Các vấn đề liên quan