2012-06-27 18 views
2

我在線閱讀book。它給出了一個回調模式的例子如下。一個Javascript回調模式的例子 - 它真的更有效嗎?

var findNodes = function() { 
    var i = 100000, // big, heavy loop 
     nodes = [], // stores the result 
     found; // the next node found 
    while (i) { 
     i -= 1; 
     // complex logic here... 
     nodes.push(found); 
    } 
    return nodes; 
}; 
var hide = function (nodes) { 
    var i = 0, max = nodes.length; 
    for (; i < max; i += 1) { 
     nodes[i].style.display = "none"; 
    } 
}; 

// executing the functions 
hide(findNodes()); 

它說這不是有效的,因爲它循環遍歷找到的節點兩次,下面的代碼更有效率。

// refactored findNodes() to accept a callback 
var findNodes = function (callback) { 
    var i = 100000, 
     nodes = [], 
     found; 

    // check if callback is callable 
    if (typeof callback !== "function") { 
     callback = false; 
    } 

    while (i) { 
     i -= 1; 

     // complex logic here... 

     // now callback: 
     if (callback) { 
      callback(found); 
     } 

     nodes.push(found); 
    } 
    return nodes; 
}; 
// a callback function 
var hide = function (node) { 
    node.style.display = "none"; 
}; 

// find the nodes and hide them as you go 
findNodes(hide); 

然而,兩者都是O(n),並調用函數的開銷可能很大,這導致findNodes每次迭代()(與回調)需要更多的時間。所以我想知道這個修改是否真的與作者所說的不同。我該如何衡量這兩種工具的成本?

+0

這將取決於某些部分平均有多少節點'findNodes'要返回。如果它很小,那麼兩種方法的性能都差不多。對於非常大的回調可能會更好。然而,由於「複雜邏輯」是由'findNodes'處理的(在第一個例子中),那麼進一步的迭代不應該太昂貴。 –

+1

http://jsperf.com/normal-vs-callback – Christoph

回答

3

取決於數組的大小,只有一圈的示例可以更有效的是

但是,您的擔憂是正確的。尤其是在老一點的JS引擎中,函數調用會有很大的開銷。

與所有性能優化一樣,這是您應該測量的。使用分析器來測試代碼以找到瓶頸,然後進行優化,然後重新運行分析以查明它是否有積極影響。

2

我把兩個例子在兩個功能在一個HTML文件,以及所使用的瀏覽器的控制檯到時刻它們,這樣的:

console.time('slow'); slow(); console.timeEnd('slow'); 
console.time('fast'); fast(); console.timeEnd('fast'); 

這表明第一實施例中,「低效率」一,運行是第二次實施的兩倍。

+0

http://jsperf.com/normal-vs-callback但也許可能有一些用例,它是另一種方式。 – Christoph

+2

我幾乎試圖投下這個答案!你已經發布了*最少*相關部分的代碼,即你如何計時的電話。你沒有提到a)你如何實現'findNodes'的複雜邏輯b)'findNodes'選擇了多少個節點c)你使用了哪種類型的標記元素...... –

相關問題