2

オンラインの本を読みました。コールバックパターンの例を次のように示しました。

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());

見つかったノードを2回ループするため、これは効率的ではないと言われています。次のコードの方が効率的です。

// 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()(コールバックを使用)の各反復に時間がかかります。ですから、作者が言ったように、この変更は本当に違うのだろうかと思います。そして、2つの道具のコストをどのように測定する必要がありますか?

4

2 に答える 2

3

配列のサイズによっては、1回だけループする例のが効率的です。

しかし、あなたの懸念は正しいです。特に少し古いJSエンジンでは、関数呼び出しにかなりのオーバーヘッドがあります。

すべてのパフォーマンスの最適化と同様に、これは測定する必要があるものです。プロファイラーを使用してコードをテストし、ボトルネックを見つけてから最適化し、プロファイリングを再実行して、プラスの効果があるかどうかを確認します。

于 2012-06-27T08:51:26.137 に答える
2

2つの例をHTMLファイルの2つの関数に入れ、Chromeコンソールを使用して次のように時間を計りました。

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

これは、最初の例である「非効率的な」例が、2番目の実装の2倍の速度で実行されることを示しています。

于 2012-06-27T08:55:22.807 に答える