2013-03-02 6 views
10

これは特にあいまいな点のように思えるかもしれませんが、私はJavascript言語全体(より具体的には最高の効率的なプラクティス)を身に付けようとしています。JSプロトタイプ関数をディクショナリよりも速く別々に定義するのはなぜですか?

http://jsperf.com/で理論をテストしながら、私はいくつかの奇妙な結果を思い付いた:

たちは次のように定義された2つの "同一" のプロトタイプを、持っているとします

オブジェクト1

var Object1 = function() {} 

Object1.prototype.defaults = { 
    radius: 400, 
    up: 1 
} 

Object1.prototype.centerOffset = function() { 
    return this.defaults.radius*this.defaults.up; 
} 

Object2

var Object2 = function() {} 

Object2.prototype = { 
    defaults: { 
     radius: 400, 
     up: 1 
    }, 

    centerOffset: function() { 
     return this.defaults.radius*this.defaults.up; 
    } 
} 

オブジェクト1一貫した(マージナル場合:〜3%)があります。

var o = new Object1(); 
var offset = o.centerOffset(); 

&

var o = new Object2(); 
var offset = o.centerOffset(); 

あなたがテストを実行することができ、以下の簡単な操作を実行するときObject2に以上の速度の利点をあなた自身here。私はOSX 10.6.8でChrome 25を使用しています。私が知りたいのですがどのような

はこれです:

  • このパフォーマンスの違いの理由(複数可)とは何ですか?
  • このパフォーマンスは、javascriptのベストプラクティスを示していますか?

ありがとうございました。

編集:ありがとうございました - いくつか述べているように、私のところでさらにテストすると、この問題はブラウザ(またはJavascriptコンパイラ固有)であることが示唆されているようです。私はSafari、IE 10、Firefoxでさらにテストしました。 IE 10とFirefoxはどちらも同じ結果を得た。 SafariはObject2の操作をObject1の操作よりもわずかに速く(平均で約2%)実行しました。その場合のパフォーマンスの差がかなりあるように見えるので、私は外れ値(その他)が何であるか知りたいと思います。

+0

これはたぶんV8のいくつかの奇妙なことを示しているに過ぎません。 – delnan

+0

私は反対の結果Firefoxを実行していた –

+0

魅力的なので、そのコンパイラ固有...私はいくつかのより多くのブラウザテストを行い、報告します。 –

答えて

3

関数を宣言すると、そのプロトタイプ属性は、デフォルトコンストラクタを含むオブジェクトで初期化されます。

Object1では、既存のプロトタイプ関数に属性を追加しています。 Object2では、既存のプロトタイプを独自のコンストラクタレスに置き換えます。

2つは同一ではありません。

速度が異なるのはなぜですか? V8では、インスタンスを作成するたびに、オブジェクト2のプロトタイプにコンストラクタ関数を追加することができます。

また、既存のプロトタイプ関数が機械コードで実装されているため、オブジェクトをObject2.prototypeに割り当てるとプロトタイプ関数が純粋なjavascriptになり、速度が遅くなります。

異なるインタプリタがこれを異なる方法で処理するので、詳細はそれほど重要ではありません。重要なのは、Object1とObject2がまったく同じではないことを認識することです。

+0

私はあなたの応答が好きです。実装の最適化が優先されている可能性は考慮していませんでした。 –

+0

私は正確に私が求めていたことを明確にしたので、私はあなたの答えを受け入れました。私は、ここで何が起こっているのかを本当に理解するためには、私のC++スキルをブラッシュアップし、Chromium/V8ソースを見てみる必要があると私は思っています。 –

0

私は、Object1内のプロトタイプを追加し、Object2で上書きすることをお勧めします。検証するために、私は2番目のパフォーマンス例を作成しました:http://jsperf.com/correct-way-to-declare-prototype-functions/2

関数が割り当てられる前に、 "Object1.prototype = {}"を追加しました。パフォーマンスはObject1とObject2の間でほぼ同じです(少なくともChromeでは)。

関連する問題