2012-11-19 39 views
2

在Chrome中進行測試時,反轉數組的簡單實現速度是Javascript中內置函數的兩倍。 V8在做什麼?下面是測試:在版本20.0.1132.47 Ubuntu的爲什麼自定義數組的反向執行速度比使用V8中的.reverse()快兩倍

var newArr = []; 
var newArrDefault = []; 
for(var i = 0; i < 10000000; i++){ 
    newArr[i] = i; 
    newArrDefault[i] = i; 
} 


var startDefault = new Date(); 
newArrDefault.reverse(); 
console.log("Built in method took " + (new Date().getTime() - startDefault.getTime())); 


var start = new Date(); 
for(var i = 0; i < newArr.length/2; i++){ 
    var tmp = newArr[i]; 
    newArr[i] = newArr[newArr.length-i-1]; 
    newArr[newArr.length-i-1] = tmp; 
} 
console.log("Custom method took " + (new Date().getTime() - start.getTime())); 

結果12.04(144678):

Built in method took 149 
Custom method took 71 
+2

您的結果在Chrome的jsPerf http://jsperf.com/arrayreversecomparison中得到確認。自定義功能比內置功能更快。這裏是'.reverse()'的實現規範。http://stackoverflow.com/a/7912713/816620 – jfriend00

+1

@ jfriend00實際上,jsperf案例的結果顯示:內置函數比自定義函數更快。 –

+1

一個區別是符合實現測試每個索引是否存在成員。 OP沒有,所以它會創建以前沒有的成員(因此不符合ECMA-262)。每個索引(上和下)應首先用'hasOwnProperty'進行測試。 – RobG

回答

2

對於它的樂趣不需要額外的時間,我實現了規範,像這樣:

var upper, upperExists, lowerExists, lowerValue, upperValue; 

for(var lower = 0, len = newArr.length >>> 0, middle = Math.floor(len/2); lower != middle; ++lower) { 
    upper = len - lower - 1; 
    lowerValue = newArr[lower]; 
    upperValue = newArr[upper]; 
    lowerExists = newArr.hasOwnProperty(lower); 
    upperExists = newArr.hasOwnProperty(upper); 

    if (lowerExists && upperExists) { 
     newArr[lower] = upperValue; 
     newArr[upper] = lowerValue; 
    } else if (upperExists) { 
     newArr[lower] = upperValue; 
     delete newArr[upper]; 
    } else if (lowerExists) { 
     newArr[upper] = lowerValue; 
     delete newArr[lower]; 
    } 
} 

可以找到jsperf here。它包含了大量的代碼來處理缺失的條目,這就是爲什麼它比原生代碼和代碼都慢很多(某些優化可能是可能的,但它不會影響性能)。你的代碼和本地實現之間的性能差異並不是很確定。

在大多數情況下,數組是一個連續的值塊,兩者之間沒有間隔,所以你應該使用這種類型的代碼來安全;只要您知道區別:)

-3

這是因爲V8調換整個數組,作爲您的自定義功能 '燒蠟燭'兩端。 IE同時添加第一個和最後一個。

例如,V8執行以下操作(雖然可能不完全):

function rev(arr) { 
    for (var a = Array(arr.length), b = 0; b < arr.length; b++) { 
     a[b] = arr[b]; 
    } 
    return a; 
} 

這可以解釋爲什麼你的內置函數試驗了兩次只要自定義函數(記住,V8編譯JavaScript的成機器代碼在運行時,所以改爲字節碼,轉碼成機器代碼,然後執行)

+1

OP的例子是不公平的?怎麼樣?這是顛倒數組的一個非常典型的方式。爲什麼它在奇數數組上不正確?中間指數不需要被觸及。 –

+0

啊,那是對的。我的邏輯失敗了,編輯刪除評論 – SReject

+0

你能解釋一下「轉換整個數組」的含義嗎? –

相關問題