1. 程式人生 > >JS之for迴圈優化

JS之for迴圈優化

眾所周知Js中的迴圈大致可以分為4中: 
1.for迴圈 
Javascript程式碼  收藏程式碼
  1. for(var i=0;i<10;i++){  
  2.   //迴圈主題  
  3. }  

其中for迴圈是最常見的迴圈結構,由四部分組成:初始化、前測條件、後執行體、迴圈體。當代碼執行遇到for迴圈時,先執行初始化程式碼,然後進入前側條件。如果前側條件為true,則執行迴圈體。迴圈體執行完後,後執行程式碼開始執行。 
2. while 迴圈  
while迴圈是最簡單的前測迴圈,有一個前測條件和一個迴圈體構成: 
Javascript程式碼  收藏程式碼
  1. var  i = 0;  
  2. while(i < 10){  
  3.    //迴圈主題
      
  4.    i++;  
  5. }  

3. do..while迴圈  
do-while 迴圈是js中唯一一種後測迴圈,由兩部分組成,迴圈體和後測條件 
Javascript程式碼  收藏程式碼
  1. var i = 0;  
  2. do{  
  3.     //迴圈體  
  4. }while(i++ < 10)  

在do-while中至少會執行一次迴圈體 
4 for-in迴圈 
該迴圈有一個特別的用途:可以列舉任何物件的屬性名。 
Javascript程式碼  收藏程式碼
  1. for(var prop in object){  
  2.    //迴圈體  
  3. }  

迴圈體每次執行時,prop變數被賦值為object的一個屬性名,直到所有屬性遍歷完成才返回。所返回的屬性包括物件例項屬性和從原型鏈中繼承而來的屬性 


以後對4中迴圈進行了大致的介紹,接下來說說如何在進行相關係能提升 
4中迴圈型別中,只有for-in迴圈比其他幾種明顯要慢:主要原因在於每次迭代操作會同時搜尋例項或原型屬性,每次迭代都會產生更多開銷。 

如果迴圈型別與效能無關,可以從以下兩個可選因素來提高整體效能 
1.每次迭代處理的事務 
2.迭代的次數 

減少迭代的工作量 
很明顯,如果一次迴圈迭代要花很長時間去執行,那麼多次迴圈需要花更多的時間。一個提升迴圈整體速度的好方法就是限制迴圈中耗時的運算元量。 
一個典型的陣列處理迴圈可以採用三種迴圈中的任何一種。最常見的寫法如下: 
Javascript程式碼  收藏程式碼
  1. for(var i = 0; i < items.length; i++){  
  2.     process(items[i]);  
  3. }  
  4. var j = 0;  
  5. while(j < items.length){  
  6.     process(items[j]);  
  7. }  
  8. var k = 0;  
  9. do{  
  10.    process(items[k]);  
  11. }while(k < items.length);  

   上面的每個迴圈中,每次進行迴圈體時都會產生如下操作: 
   1. 一次控制條件中的屬性查詢(items.length) 
   2. 一次控制條件中的數值大小的比較(i<items.length) 
   3. 一次控制條件結果是否為true的比較(i<items.length == true) 
   4. 一次自增操作(i++) 
   5. 一次陣列查詢(items[i]) 
   6. 一次函式呼叫( process(items[j]);) 

   這些簡單迴圈中,儘管程式碼不多,但每次迭代都要進行許多操作。程式碼執行速度很大晨讀上取決於函式process()對每個陣列項的操作,儘管如此,減少每次迭代中的操作能大幅提高迴圈的整體效能。 
   優化迴圈的第一步就是減少物件成員及陣列項的查詢次數。前面例子中每次迴圈都要查詢items.length,這樣做很耗時,由於該值在迴圈執行過程中從未變過,因此產生了不必要的效能損失,提高整個迴圈的效能很簡單,只查詢一次屬性,並把值儲存到一個區域性變數中,然後在控制條件中使用整個變數 
Javascript程式碼  收藏程式碼
  1. for(var i = 0,len = item.length; i < len; i++){  
  2.     process(items[i]);  
  3. }  
  4. var j = 0,  
  5.     len = items.length;  
  6. while(j < len ){  
  7.     process(items[j]);  
  8. }  
  9. var k = 0,  
  10.     num = items.length;  
  11. do{  
  12.    process(items[k]);  
  13. }while(k < num);  


   還可以通過倒序迴圈來進行。 

減少迭代次數 

   即使是迴圈體中最快的程式碼,累計迭代上千次也會慢下來。此外,迴圈體執行時也會帶來小效能開銷,不僅僅是增加總體執行時間。減少迭代次數能獲得更加顯著的效能提升。下面介紹一種廣為人知的限制迴圈迭代次數的模式被稱為“達夫裝置(Duff's Device)”: 
   Duff's Device 是一個迴圈體展開技術,使得一次迭代實際執行了多次迭代的操作 
Javascript程式碼  收藏程式碼
  1. var iterations = Math.floor(items.length/8),  
  2.     startAt = items.length%8,  
  3.     i = 0;  
  4. do{  
  5.     switch(startAt){  
  6.         case 0 : process(items[i++]);  
  7.         case 7 : process(items[i++]);  
  8.         case 6 : process(items[i++]);  
  9.         case 5 : process(items[i++]);  
  10.         case 4 : process(items[i++]);  
  11.         case 3 : process(items[i++]);  
  12.         case 2 : process(items[i++]);  
  13.         case 1 : process(items[i++]);  
  14.     }  
  15.     startAt =  0;  
  16.  }while(--iterations);