2017-09-03 23 views
1

鏈接速度較慢,如果你喜歡它的格式,以jsperf:https://jsperf.com/test-array-vs-loop-vs-loop-optimized的Javascript:爲什麼我的優化環比比較幼稚一個

我試圖舊jsperf環路VS過濾器,我試圖通過預先分配的優化循環數組,如果大小正確,並避免項目長度重新計算。問題是,它並沒有對我的Chrome 60

這裏的運行速度是代碼:

var items = []; 
var names = ['george', 'nick', 'jack', 'herodotus', 'joanne']; 
for (var i = 0; i < 2000; i++) { 
    var obj = { 
     name: names[i % 5] + '-' + i, 
     age: i % 10 + 15 
    }; 
    items.push(obj); 
} 

function filter_callback(item) { 
    return (item.age == '18'); 
} 

function test_filter() { 
    var aged_18_filter = items.filter(filter_callback); 
} 

function test_loop() { 
    var aged_18_loop = []; 
    for (var i = 0; i < items.length; i++) { 
     if (items[i].age == '18') aged_18_loop.push(items[i]); 
    } 
} 

function test_loop_optimized() { 
    var length=items.length 
    var aged_18_loop = new Array(length); 
    for (var i = 0; i < length; i++) { 
     if (items[i].age == '18') aged_18_loop[i]=items[i]; 
    } 
} 

編輯:結果是大約39281 OPS /秒​​的正常循環,37389個OPS /秒​​「優化「循環。在i7 3610QM上。

+1

我不明白你的優化是什麼。 – ninesalt

+1

提示:如果您嘗試過濾,'new Array(length)'有*錯誤*大小,並且通過分配給'aged_18_loop [i]'而不是數組末尾,您甚至會創建一個稀疏數組孔。我不認爲這就是你想要的。 – Bergi

+0

你得到了什麼結果,你可以發佈它們嗎?我手邊沒有任何Chrome 60。 – Bergi

回答

4

我試圖如果正確的尺寸

預先分配的陣列,以優化循環,但你沒有那個。過濾結果通常不會與輸入大小相同。通過不在末尾添加數組(使用push)並始終將索引分配給i,您甚至可以創建一個稀疏數組。 (鑑於你的樣本很小,至少沒有太大的影響)。

正確的方法可能是

function test_loop_optimized() { 
    var length = items.length; 
    // let's guess that the result will have about a fifth of the size 
    var result = new Array(Math.round(length/5)); 
    var i = 0; 
    var j = 0; 
    while (i < length) { 
     var item = items[i++]; 
     if (item.age == '18') 
      result[j++] = item; 
    } 
    result.length = j; // just in case we guessed too high 
    return result; 
} 

...,避免項目長度重新計算

這是一個微不足道的優化的JS引擎確實弄清楚本身申請。實際上訪問.length並不是很慢。除非有什麼奇怪的事情發生,否則你不會從拼寫出來。