6

javascriptでのメソッド呼び出しのパフォーマンスの高い実行と実行時間の一貫性の間の最良の妥協点は何ですか?

私はまだjavascriptを学んでおり、ほとんどすべてにプロトタイプを使用します(つまり、ここではブレンダン・アイヒ)が、関数クロージャーからより良いパフォーマンスと一貫性を見つけていると思います(おそらく最適化しすぎていることはわかっています)。私がテストしてきた 1 つのプロトタイプ パターン:

function PrototypeA() {}
PrototypeA.prototype.a = 0;
PrototypeA.prototype.b = 0;
PrototypeA.prototype.someMath = function() {
    this.a += 1;
    this.b += 2;
};
var Test = new PrototypeA();
Test.someMath();

この (素晴らしい!)ベンチマーク クロージャーへの投稿を読んだ後に決定しました。私が向かっている現在の閉鎖パターン:

var SubModule = new((function() {
    var a = 0;
    var b = 0;
    var someMath = function() {
        a += 1;
        b += 2;
    };
    return function() {
        this.someMath = someMath
    };
})())();

ベンチマークでコンストラクターを呼び出したり、さまざまなスコープ トラバーサル パスを引き起こす方法でメソッドを呼び出したりするなど、テスト セットアップのエラーが原因で、さまざまなパターンの多くのベンチマークが誤解を招くことがわかっています。メソッドの実行をテストしようとしています。

ローカルで多くのベンチマーク (多くの異なるパターンにわたる benchmark.js) の後、注目すべきパターンを提示しました。

Jsperfはこちら

私の調査結果は、適切に編成されたクロージャーは、他の多くのタイプのオブジェクトのように実行時間がずれていないことを裏付けているようです (私は「タイプ」という用語を大まかに使用しています)。ベンチマークまたはセットアップの数値またはエラーが原因で、完全に間違っている可能性があることを認識しています。

ご覧いただきありがとうございます。

4

2 に答える 2

10

あなたのユースケースはアニメーションなので、クロージャに固執したいと考えています。JavaScript の簡単な経験則は、「数.が多いほど、コードの処理速度が遅くなる」というものです。あなたがjsperfに投稿した例では、最も遅いものはthisかなり参照しているものです。これを行うたびに、エンジンは現在のオブジェクトを調べて、アクセスしようとしているものがオブジェクトですぐに利用できるかどうか、およびプロトタイプ チェーンを検索する必要があるかどうかを判断する必要があります。物事の閉鎖側では、あなたが書いた関数によって事前に決定された、かなり制限されたスコープを参照しています。エンジンがしなければならないことは、そのスコープを見て変数を参照できることです。

さて、いくつかの落とし穴があります。まず、 をthis1 回か 2 回参照するだけの場合は、 の使用が大幅に高速になります。この例ではそうではありませんが、言及する価値があります。への参照を追加する回数が増えるほどthis、プロトタイプに依存するコードの動作が遅くなります。例として、この単純なパフォーマンスを見てください。第 2 に、これらのモジュールを多数構築している場合 (たとえば、データ グリッドを構築している場合)、クロージャによって構築が非常に遅くなり、大量のメモリが浪費されます。速度の違いについては、この例を参照してください。メソッドやプロパティを追加すればするほど、状況は悪化します。これは、毎回新しいクロージャを作成すると独自の関数とプロパティが作成されるのに対し、プロトタイプ ベースのクロージャは同じものを再利用するだけだからです。

どちらの場合でも、プログラミングしている状況を実際に見ることをお勧めします。ほとんどの場合、プロトタイプを使用するのが道です - 可読性[場合によっては]、再利用性、拡張性..しかし、それらが遅すぎる場合は、それらを使用することはできません. そうは言っても、2 つの概念を組み合わせて、再利用可能で、頻繁にヒットしないメソッド用のモジュール式のセットアップを提供することに問題はありません。たとえば、「Mixins」を使用してみてください。

var Mixin = {
    interval: 100,
    finish: function () { window.clearInterval(this.intervalRef); },
    start: function (callback) { this.intervalRef = window.setInterval(callback, this.interval)
};

var Module = (function () {
    function getMessage () {
        return "weee!";
    }
    var somethingThatReallyNeedsSpeed = function () {
        var iterations, self = this;

        this.start(function () {
            console.log(getMessage());
            iterations++;
            if(iterations > 10000) {
               self.finish();
            }
        });
    }
    somethingThatReallyNeedsSpeed.prototype = Mixin;
    return somethingThatReallyNeedsSpeed;
})();

この例では、プロトタイプがMixinオブジェクトを参照するように設定されているだけなので、構築速度はそれほど悪くはありません - 特別な関数が毎回構築する必要のない 2 つのメソッドとプロパティがありますが、それでも利用可能ですthis.

</rant>

于 2013-05-20T08:50:24.207 に答える