2012-06-06 64 views
0

請告訴我,將值推入數組的更快方法是什麼?用法Array.push方法

我寫了一個簡單的測試來比較pusha[a.length]=方法:

push.js:

self.onmessage = function (event) { 
    var n = Number(event.data), 
     i, 
     pushAr = [], 
     pushStart, 
     pushDuration, 
     ar = [], 
     start, 
     duration, 
     message; 

    // Push 
    pushStart = new Date(); 
    for (i = 0; i < n; i += 1) { 
    pushAr.push(i); 
    } 
    pushDuration = new Date() - pushStart; 

    // explicit 
    start = new Date(); 
    for (i = 0; i < n; i += 1) { 
    ar[ar.length] = i; 
    } 
    duration = new Date() - start; 

    message = "N = " + n; 
    message += "\nPush duration: " + pushDuration + "; "; 
    message += "Length duration: " + duration; 

    self.postMessage(message); 
}; 

main.js:

var worker = new Worker("push.js"), 
    i; 

worker.onmessage = function (event) { 
    console.log(event.data); 
}; 

for (i = 4; i < 8; i += 1) { 
    worker.postMessage(Math.pow(10, i)); 
} 

而且我得到了以下結果:

鉻:

N = 10000 
Push duration: 0; Length duration: 0 
N = 100000 
Push duration: 3; Length duration: 5 
N = 1000000 
Push duration: 56; Length duration: 90 
N = 10000000 
Push duration: 807; Length duration: 948 

Safari瀏覽器:

N = 10000 
Push duration: 1; Length duration: 4 
N = 100000 
Push duration: 2; Length duration: 2 
N = 1000000 
Push duration: 27; Length duration: 41 
N = 10000000 
Push duration: 283; Length duration: 461 

火狐:

N = 10000 
Push duration: 1; Length duration: 0 
N = 100000 
Push duration: 2; Length duration: 2 
N = 1000000 
Push duration: 11; Length duration: 20 
N = 10000000 
Push duration: 279; Length duration: 412 

好像Array.push比較快,但是爲什麼有些庫使用array length呢?這種方法有哪些獎勵?爲什麼Chrome如此之慢?也許有更快的方法存在?

+0

性能差異太依賴於實施,並不足以產生顯着收益。不要[過早優化](http://c2.com/cgi/wiki?PrematureOptimization);編寫最清晰的代碼,然後配置文件,然後優化。 – outis

+1

最快的方法是跟蹤索引(array [i] = value),而不是在每次迭代中對其進行測量。 – kennebec

回答

2

兩種方法都完全相同,推送速度更快,因爲相同的算法(獲取數組長度)在腳本引擎內運行,而不在腳本中運行。如果您需要該表達式的結果爲新值,則可以使用ar [ar.length],如鏈接分配somevar = ar[ar.length] = "some new value"

我發現了一些其他可能的用法 - 與舊版本的JavaScript引擎的兼容性。在JScript 5.0版的Microsoft文檔中,沒有提及Array對象中的push方法。我實際上從當時(2000年左右)找到了自己的代碼,它實際上使用images[images.length] = s代碼。所以,也許數組並不總是有推式方法。

P.S.是的,MSDN cocumentation推送方法說版本5.5是必需的,這甚至不是在Windows 2000

+0

同意,但返回的值並不重要。如果我們進入'push'實現,我們可以看到,該算法不僅僅是將值推入數組,還有一些對參數類型等的檢查。它如何更快?本機優化? – ValeriiVasin

+1

是的,陣列是由供應商非常微觀優化;他們在「最快引擎」討論中是很好的論據。你使用的版本更多的是相信的問題:-) http:// jsperf。com/index-vs-push/2 – Bergi

+0

偉大的測試和網站。 – ValeriiVasin

1

一些庫(如jQuery的)使用ar[ar.length],因爲它們不使用真正陣列,但ArrayObjects,它們沒有.push方法,因爲它們是對象而不是數組。用來解決這一問題,您可能經常會遇到另一個竅門,是

Array.prototype.push.call(arrObj,'newValue'); 

的另一個原因使用ar[ar.length]由熊貓34位:鏈分配..!

+1

但是他們必須使用'ar [ar.length ++]',不是嗎? – Bergi

+0

是的,它們應該增加ArrayObject的長度,儘管不一定在賦值本身。 –

+0

好點,謝謝。 – ValeriiVasin