14

最近、頻繁に作成される値オブジェクトのコードを最適化しようとしました。(3 次元ベクトル、fwiw)

私が試したことの 1 つは、コンストラクター関数を匿名メソッド ファクトリ パターンから通常の JavaScript コンストラクターに変換することでした。

JavaScript コンストラクター/ファクトリー パターンに関する私の最後の質問では、「新しい」コンストラクターと通常のコンストラクターの使用が強く推奨されていたので、これは私を驚かせた深刻なパフォーマンスの低下につながりました。

私のテストが単純すぎるか、単純に間違っているか、Chrome の JavaScript エンジンで行われた最近のパフォーマンスの最適化の結果か、または上記のすべてが原因である可能性があります。いずれにせよ、私の「最適化」がパフォーマンスの低下につながった理由を本当に知りたいです-そして-最も重要なのは、私のjsperfテストランに明らかな問題はありますか?

4

2 に答える 2

4

テスト間の主な違いは次のとおりです。

  • {}は よりもはるかに高速ですnew Objectnew。これは、を使用するよりも単純に遅いことを示唆してい{}ます。[](とも同様ですnew Array。)

  • テストは異なる結果を生成します:makeファクトリ関数の結果はMakeオブジェクトではありません。構築された には、すべてのオブジェクトMakeで共有されるプロトタイプがあります。Makeファクトリ関数の結果は単なる でObjectあり、そのプロトタイプ チェーン ( Object.prototype) には 1 つのプロトタイプがありますが、Make で構築されたオブジェクトには 2 つの ( Make.prototype、その後にObject.prototype) があります。

    非標準のプロパティを使用して、実際にオブジェクトを返すファクトリ関数(代わりに単純な ) を使用して、 test のフォークを作成しましたが、コンストラクターを使用するよりもはるかに低速です。IE は をサポートしていませんが、Firefox と Chrome からの結果はかなり明確に見えます。MakeObject__proto____proto__

于 2013-01-02T20:31:03.413 に答える
3

コンストラクター関数が最適化する対象の 1 つは、共有プロパティ (通常はメソッド) です。多数のオブジェクトが同じ関数をメソッドとして使用するか、他の名前付きプロパティを共有する場合、プロトタイプへの 1 つの割り当ては、コンストラクターから作成されたすべてのオブジェクト間でプロパティの 1 つのインスタンスを共有し、メモリ オーバーヘッドを削減し、繰り返す必要はありません。作成されたすべてのオブジェクトにそのような各プロパティを割り当て、構築時間のオーバーヘッドを削減します。

サンプルにはそのようなプロパティが含まれていないため、そのような利点は見られません。しかし、作成したオブジェクトの共有プロパティがプロダクション コードに含まれていない場合は、コンストラクターに切り替える理由がない可能性があります。

たとえば、次のようなコードがあるとします。

function make(p) {
    return {
        parm: p,
        addTwo: function() {return this.parm + 2;},
        double: function() {return this.parm * 2;},
        square: function() {return this.parm * this.parm;}
    };
};

おそらくこれよりも遅く実行されます。

function Make(p) {
    this.parm = p;
}
Make.prototype.addTwo = function() {return this.parm + 2;};
Make.prototype.double = function() {return this.parm * 2;}
Make.prototype.square = function() {return this.parm * this.parm;}

多くのインスタンスを作成すると、さらに多くのメモリが必要になります。

于 2013-01-02T20:29:04.187 に答える