2012-10-09 138 views
4

正如我的研究讓我相信循環是JavaScript語言中最快的迭代構造。我在想,爲for循環聲明一個條件長度值會更快......爲了使它更清晰,您認爲以下哪個更快?FOR循環中的性能

例ONE

for(var i = 0; i < myLargeArray.length; i++) { 
    console.log(myLargeArray[i]); 
} 

例如兩個

var count = myLargeArray.length; 
for(var i = 0; i < count; i++) { 
    console.log(myLargeArray[i]); 
} 

我的邏輯如下,關於例如一個在每個迭代中訪問在每次迭代myLargeArray的長度是計算上更昂貴然後訪問一個簡單的整數值,如例2所示?

+2

您是否試過編寫性能測試? – Spoike

+0

不,總是有這麼多的圍繞這樣的測試和他們的參數的爭議... – AndrewMcLagan

+2

你基本上回答自己。它高度依賴於條件,所以它基本上是不可測試的。你提供了一個具體的例子,你可以真正測試這個具體的例子。 – Dykam

回答

7

與以下某些語句相反,不會在每次迭代中計算數組的長度。 Array的長度是通過修改操作設置的屬性,如pop,push,shift,unshift,splice等等。

雖然自以來您將會看到小幅度的性能降低,但屬性查找的成本高於本地變量。因此緩存長度是一個好主意。然而,除非你處理大數據集,否則你不會看到很大的差異。

儘管在每次迭代中確實計算了長度,但還是有一個特例。 HTML節點集合就是這種情況。由於這些是活動對象,因此它的長度不是數組中的屬性。如果你這樣做:

for (var i=0; i < collection.length; i++) { 
    collection[i] 
}; 

然後集合在每次迭代時被解析。

作爲優化for循環中,我通常使用這些技術來緩存:

// if order is of no concern, just iterate from length-1 to 0 
for (var i = arr.length - 1; i >= 0; i--){ 
    arr[i] 
}; 

// use the for loop statement to set up scoped variables 
for (var i=0, length = arr.length; i < length; i++) { 
    // do something 
} 
0

是你是對myLargeArray.length正在計算循環(第一實例)的每一次迭代。 link1link2

for(var i = 0; i < myLargeArray.length; i++) { 
    console.log(myLargeArray[i]); 
} 
+0

注意長度在查看時不計算,添加或移除項目時會更改註釋長度(簡單地增加或減少),因此這不是OP的性能差異。 – Dykam

+1

@Dykam我認爲閱讀一個數組的長度,然後比較比計算直接比較整數。 – Anoop

+0

你的答案改變了。在計算數組的長度之前。我的評論現在無關緊要。 – Dykam

1

我不認爲你有什麼用第二個版本時都需要,但我會感到驚訝失去,如果數組長度實際上得到每次都從頭開始計算了,除非第一種方法數組實際上被循環變異。

不要忘記,你可以在for的第一部分聲明多個變量:

for(var i = 0, count = myLargeArray.length; i < count; i++) { 
    console.log(myLargeArray[i]); 
} 
+0

+1在初始化語句中聲明瞭兩個變量 – AndrewMcLagan

3

JavaScript Garden,於JavaScript的怪癖一個很好的資源。

儘管長度屬性是在數組本身上定義的,但在循環的每次迭代中,仍然存在 的查找開銷。 雖然最近的JavaScript引擎可能會在此 的情況下應用優化,但是無法告訴代碼是否會在這些較新的引擎中的某一個上運行。

+0

我剛剛在chrome中做了一個快速髒測試,它對於兩個循環都有完全相同的結果,也就是上面的確切代碼,考慮myLargeArray是1000個元素長度 – AndrewMcLagan

1

High Performance JavaScript

減少每次迭代的工作:

//original loops 
for (var i=0; i < items.length; i++){ 
process(items[i]); 
} 

var j=0; 
while (j < items.length){ 
process(items[j++]]); 
} 

var k=0; 
do { 
process(items[k++]); 
} while (k < items.length); 



//minimizing property lookups 
for (var i=0, len=items.length; i < len; i++){ 
process(items[i]); 
} 

var j=0, 
count = items.length; 
while (j < count){ 
process(items[j++]]); 
} 

var k=0, 
num = items.length; 
do { 
process(items[k++]); 
} while (k < num); 


//minimizing property lookups and reversing 
for (var i=items.length; i--;){ 
process(items[i]); 
} 

var j = items.length; 
while (j--){ 
process(items[j]]); 
} 

var k = items.length-1; 
do { 
process(items[k]); 
} while (k--); 

減少迭代次數:

//credit: Jeff Greenberg 
var i = items.length % 8; 
while(i){ 
process(items[i--]); 
} 
i = Math.floor(items.length/8); 
while(i){ 
process(items[i--]); 
process(items[i--]); 
process(items[i--]); 
process(items[i--]); 
process(items[i--]); 
process(items[i--]); 
process(items[i--]); 
process(items[i--]); 
} 

請參閱JavaScript Optimization

+0

只需提及方法如果順序不重要,「//最小化屬性查找和反轉」是很好的 – GibboK