関数呼び出しはごくわずかであるか、JSがこれまでになかったコンパイル済み言語で最適化することさえできます。それを超えて、ブラウザに大きく依存します。
それらは、JSが主にごく最近まで行ってきた通訳言語でのすべてのパフォーマンスの死です。最近のほとんどのブラウザーには、過去のJSインタープリターからの大幅なアップグレードであるJIT(Just In Time)コンパイラーがありますが、JSの呼び出しオブジェクトは実際に呼び出されているものを判別する必要があるため、別のスコープへの関数呼び出しにはまだオーバーヘッドがかかると思います。さまざまなスコープチェーンを上下に移動します。
したがって、原則として、IE8以前のバージョンのChromeとFirefoxを気にする場合は、関数呼び出し期間を避けてください。特にループ内。JITブラウザーの場合、他の関数内で定義された関数が一般的に有益であると期待します(ただし、これはIE9のまったく新しいテクノロジーであり、他のすべての人にとっては比較的新しいため、テストします)。
注意すべきもう1つのこと。関数が特に複雑な場合、JITはそれらを最適化するために何もしない可能性があります。
https://groups.google.com/forum/#!msg/closure-compiler-discuss/4B4IcUJ4SUA/OqYWpSklTE4J
ただし、理解しておくべき重要なことは、関数内の関数のように、何かがロックされてコンテキスト内でのみ呼び出される場合、JITは簡単に最適化できるはずです。関数の外部で定義され、その関数のどの定義が正確に呼び出されているかを判別する必要があります。それは外部機能にある可能性があります。グローバルである可能性があります。これは、ウィンドウオブジェクトのコンストラクターのプロトタイプなどのプロパティである可能性があります。関数がファーストクラスである言語では、データを渡すのと同じ方法で参照を引数として渡すことができるため、そのステップを実際に回避することはできません。あなたの現在の文脈の外。
したがって、X内でhypoを定義して、何が起こるかを確認してください。
JITでまだ価値があるかもしれない、解釈された時代からのもう2つの一般的なヒント:
'。' のような演算子someObject.property
は、キャッシュする価値のあるプロセスです。使用するたびに関連する呼び出しオブジェクト検索プロセスがあるため、オーバーヘッドが発生します。親オブジェクトまたはプロトタイプを変更すると、特定のコンテキスト外で実際に参照するものが変更される可能性があるため、Chromeはこのプロセスの結果を保持しないと思います。あなたの例では、xがループによって使用されている場合(xがJITのループと同じ関数で定義されている場合は大丈夫または役立つ可能性があります-インタープリターでの殺人)、使用する前にMath.sqrtを変数に割り当ててみますハイポで。現在の関数のコンテキスト外のものへの参照が多すぎると、一部のJITは、最適化するのに苦労する価値がないと判断する可能性がありますが、それは私の側の純粋な推測です。
配列をループさせる最も速い方法は、おそらく次のとおりです。
//assume a giant array called someArray
var i = someArray.length; //note the property lookup process being cached here
//'someArray.reverse()' if original order isimportant
while(i--){
//now do stuff with someArray[i];
}
注:コードブロックが何らかの理由でここで機能していません。
このようにすると、基本的にインクリメント/デクリメントステップと論理比較がデクリメントだけに変換され、左右の比較演算子が完全に不要になるため、便利です。JSでは、右側のデクリメント演算子は、iが渡されて評価され、ブロック内で使用される前にデクリメントされることを意味することに注意してください。while(0)
falseと評価されます。