2011-07-01 32 views
19

我正在實現一些自然適合地圖的代碼。但是,我有一個列表對象我要遍歷的顯著量,所以我的問題是,這是去安博最好的辦法:JQuery地圖vs Javascript地圖vs For循環

var stuff = $.map(listOfMyObjects, someFunction()) 

var stuff = listOfMyObjects.map(someFunction()) 

或只是

var stuff = new Array(); 
for(var i = 0; i < listOfmyObjects.length; i++){ 
    stuff.push(someFunction(listOfMyObjects[i])); 
} 
+0

你的例子不是等價的(也沒有使第一個代碼片斷有意義)。你是否想爲列表中的每個元素執行'someFunction'?它是否返回一個值,並且你想用返回值替換列表項?這實際上是「地圖」的想法。 –

回答

11

後者(for循環)要快得多。我記得在某處看到了一個基準,但我似乎無法找到鏈接。

如果性能確實是一個問題,那麼我會使用for循環。它並沒有真正模糊代碼。

+8

除非他將someFunction內聯到循環,否則for循環可能會與性能相近。 map本質上只是用一個額外的函數調用做同樣的事情,但性能命中來自於每次調用該函數,這會填充每個函數的作用域。 – Robert

+1

https://jsperf.com/map-vs-for-loop-performance/6 – ericn

6

首先,真Objects沒有本地.map()方法,既沒有.length屬性。所以我們要麼談論ArraysArray-like-objects(例如jQuery對象)。

但是,沒有比使用本地forwhiledo-while循環更快的迭代方式。所有其他功能操作都會執行(猜測是什麼)每個迭代所需的功能。

jQuerys的.each()只會在對象傳遞給它時執行for-in循環。這是循環對象最快的方法。您可以自己使用for-in,並保存通話費用。

可讀性方面的另一個「良好」方式是使用ES5功能,如.keys().map()。例如:

var myObj = { 
    foo: 'bar', 
    base: 'ball', 
    answer: 42, 
    illuminati: 23 
}; 

Object.keys(myObj).map(function(prop) { 
    console.log(myObj[ prop ]); 
}); 

我認爲就可讀性,便利性和性能而言,這是非常好的交易。當然,您應該使用ES5抽象庫來處理舊式瀏覽器。

但是,再次,無法在性能方面擊敗本地循環。

+0

對不起,我說錯了。我打算在列表中說出對象。編輯我的問題更有意義。 – dave

1

用你的html/javascript代碼創建一個測試用例,代碼爲jsperf

您將能夠看到最佳效果以及不同瀏覽器執行循環的速度。

我會把我的錢放在原生JavaScript循環中,但你永遠不知道。

2

+1爲Emil的「測試」答案:)這總是正確的答案。

但是,本機循環贏了,你可以通過緩存長度來做一個更好的選擇,這樣每次迭代都不會評估.length引用。

for(var i = 0, l = list.length; i < l; i++) 

或做向後

for(var i = list.length-1; i >= 0; i--) 

避免額外的VAR和,如果你可以「在線」的「someFunction」,那將是越飛越快。基本上,儘可能避免函數調用和引用。但是,只有當你真的在看細節。像這樣的優化是不太可能的。經常測試以發現瓶頸。

+3

對於(var i = array.length; i - ;)'是反向循環的更好選擇。 – sabithpocker

11

這裏是一個測試用例jsben.ch完成:http://jsben.ch/#/BQhED

它表明一個for循環的地圖比jQuery的地圖(至少在鉻)更快。

+1

我在問題中加入了第三種情況,但是您對for循環方法的建議仍然排在第一位(chrome)。 –

+0

看看d3.js和underscore.js地圖方法與這些方法的比較會很有趣。 – amergin