我在网上看了book。它给出了一个回调模式示例如下。
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 :(得分:3)
根据数组的大小,只有一次循环的示例可以更高效。
但是,您的担忧是正确的。特别是在较旧的JS引擎中,函数调用会产生很大的开销。
与所有性能优化一样,这是您应该衡量的。使用分析器测试代码以找到瓶颈,然后进行优化,然后重新运行分析以确定它是否具有正面效果。
答案 1 :(得分:2)
我将两个示例放在HTML文件中的两个函数中,并使用Chrome控制台为它们计时,如下所示:
console.time('slow'); slow(); console.timeEnd('slow');
console.time('fast'); fast(); console.timeEnd('fast');
这表明第一个例子,“效率低下”,运行速度是第二个例子的两倍。