AS3では、パフォーマンスを向上させるために、ループの外側ですべての変数を初期化する必要があると思います。これはJavaScriptにも当てはまりますか?どちらが良い/速い/ベストプラクティスですか?
var value = 0;
for (var i = 0; i < 100; i++)
{
value = somearray[i];
}
または
for (var i = 0 ; i < 100; i++)
{
var value = somearray[i];
}
AS3では、パフォーマンスを向上させるために、ループの外側ですべての変数を初期化する必要があると思います。これはJavaScriptにも当てはまりますか?どちらが良い/速い/ベストプラクティスですか?
var value = 0;
for (var i = 0; i < 100; i++)
{
value = somearray[i];
}
または
for (var i = 0 ; i < 100; i++)
{
var value = somearray[i];
}
回答:
JavaScriptでもActionScriptでも、意味やパフォーマンスに違いはありません。
varパーサーのディレクティブであり、実行時に実行されるコマンドではありません。特定の識別子がvar関数本体(*)のどこかで1回以上宣言されている場合、ブロック内でのその識別子の使用はすべてローカル変数を参照します。がループの内側、ループの外側、またはその両方valueとして宣言されているかどうかは関係ありませんvar。
したがって、最も読みやすいと思われる方を記述してください。すべての変数を関数の先頭に配置することが常に最良の方法であるというのは、クロックフォードとは同意しません。変数がコードのセクションで一時的に使用される場合は、varそのセクションで宣言することをお勧めします。そのため、セクションは独立しており、コピーして貼り付けることができます。それ以外の場合は、関連付けられているを個別に選択して移動することなく、リファクタリング中に数行のコードを新しい関数にコピーアンドペーストするvarと、誤ってグローバルになります。
特に:
for (var i; i<100; i++)
do something;
for (var i; i<100; i++)
do something else;
Crockfordは2番目を削除することをお勧めしますvar(またはvarsとvar i;上記の両方を削除します)。jslintはこれを求めます。ただし、IMOの場合var、関数の上部に簡単に忘れられるコードを追加する代わりに、両方のsを保持し、関連するすべてのコードを一緒に保持する方が保守しやすくなります。
個人的にvarは、同じ関数の他の部分で同じ変数名の別の使用法があるかどうかに関係なく、コードの独立したセクションで変数の最初の割り当てとして宣言する傾向があります。私にとってvarは、まったく宣言しなければならないのは望ましくないJSイボです(変数をデフォルトでローカルに設定する方がいいでしょう)。私は、JavaScriptでANSI C [の古いリビジョン]の制限を複製することも私の義務とは考えていません。
(*:ネストされた関数本体以外)
var関数の先頭でのみ使用されることを要求することは、偶発的なグローバル変数の作成を要求することです。また、無関係な変数の集合をすべて1つの場所で宣言しても意味がありません。特に、これらの変数の一部が使用されない場合があります。
言語にはブロックスコープがなく、関数スコープしかないので、理論的にはJavaScriptに違いはありません。
パフォーマンスの引数についてはわかりませんが、Douglas Crockfordは、varステートメントを関数本体の最初のステートメントにすることを推奨しています。JavaScriptプログラミング言語のコード規約からの引用:
JavaScriptにはブロックスコープがないため、ブロック内で変数を定義すると、他のCファミリー言語に精通したプログラマーを混乱させる可能性があります。関数の上部ですべての変数を定義します。
次の例でわかるように、彼にはポイントがあると思います。関数の先頭で変数を宣言しても、変数i がforループブロックのスコープ内に保持されていると読者が誤解することはありません。
function myFunction() {
var i; // the scope of the variables is very clear
for (i = 0; i < 10; i++) {
// ...
}
}
ecma- / javascript、実行時に変数を上げます。それを「巻き上げ」といいます。したがって、違いはありません。
letはこの回答にどのように影響しますか?
ECMA-/Javascript言語hoists関数の先頭にどこかで宣言された任意の変数。これは、この言語には他の多くのC言語に似た言語がありfunction scope、そうでないためblock scopeです。
としても知られていますlexical scopeます。
のようなものを宣言した場合
var foo = function(){
for(var i = 0; i < 10; i++){
}
};
これは次のhoistedようになります。
var foo = function(){
var i;
for(i = 0; i < 10; i++){
}
}
したがって、パフォーマンスに違いはありません(ただし、ここで完全に間違っている場合は修正してください)。関数の先頭以外の場所で変数を宣言
しないことのはるかに優れた引数は、読みやすさです。内で変数を宣言するfor-loopと、この変数はループ本体内でのみアクセスできるという誤った仮定につながる可能性がありますが、これはまったく間違っています。実際には、現在のスコープ内のどこからでもその変数にアクセスできます。
letはこの回答にどのように影響しますか?
Chromeで簡単なテストを行いました。ブラウザでフィドルを試して、結果を確認してください
var count = 100000000;
var a = 0;
console.log(new Date());
for (var i=0; i<count; i++) {
a = a + 1
}
console.log(new Date());
var j;
for (j=0; j<count; j++) {
a = a + 1;
}
console.log(new Date());
var j;
for (j=0; j<count; j++) {
var x;
x = x + 1;
}
console.log(new Date());
結果として、最後のテストには最大8秒かかり、前の2つのテストには約2秒しかかかりません。非常に再現性があり、順序に関係なく。
だから、これは私が常にループの外で変数を宣言する必要があることを証明しています。私にとって奇妙なケースは、私がifor()ステートメントで宣言する最初のケースです。これは、インデックスを事前に宣言する2番目のテストと同じくらい高速なようです。
varグローバル変数として宣言されているため、実際には何もテストするべきではありませんとにかくグローバルである。
JavaScriptは、CまたはC ++によって下部に記述された言語ですが、どちらの言語かはよくわかりません。そして、その目的の1つは、内部メモリを処理する手間を省くことです。CまたはC ++でも、ループ内で変数が宣言されている場合に大量のリソースを消費するかどうかを心配する必要はありません。JavaScriptでそれを心配する必要があるのはなぜですか?
まあ、それはあなたが達成しようとしていることに依存します... valueループブロック内の一時的な変数だけであると仮定すると、2番目の形式を使用する方がはるかに明確です。また、より論理的で冗長です。
forループの内部または外部で変数を宣言しても、違いはありません。以下は、テストするサンプルコードです。
function a() {
console.log('Function a() starts');
console.log(new Date());
var j;
for (j=0; j<100000000; j++) {
var x;
x = x + 1;
}
console.log(new Date());
console.log('Function a() Ends');
}
a()
function b() {
console.log('Function B() starts');
console.log(new Date());
var a;
var j;
for (j=0; j<100000000; j++) {
a = a + 1;
}
console.log(new Date());
console.log('Function B() Ends');
}
b()
結果は私の場合に示されました
Function a() starts
VM121:3 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:9 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:10 Function a() Ends
VM121:14 Function B() starts
VM121:15 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:21 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:22 Function B() Ends
ありがとう-MyFavs.in
let代わりにChromium 81で試してみましたが、少し遅くなる傾向があります(120対115 ms =〜6%= IMOは重要ではvarありa()ません)。
ここでの質問は、基本的にループ内で変数を宣言することです。これを行うとどうなるか考えてみてください。
var a = 30;
var a = 50;
var a = 60;
これは正しいと思いますか?いいえ...変数を何度も宣言したくないので。ループ内で変数を宣言すると、ループの実行回数を宣言しませんか?言うまでもなく、「厳密な使用」モードになっているときは平手打ちされます。人々は元の質問について考えずにクロックフォードに同意しませんでした。
したがって、変数を最初に宣言することは常に良いことです。1.読みやすくするために、2.適切な習慣を作ること。
Linux OSでChrome、Firefox、jsperfでテストを実行した後のパフォーマンスに関しては、ループ内の変数の宣言とループ外の変数の宣言の間にパフォーマンスの違いがあるように見えます。これは小さな違いですが、これは反復回数と変数宣言の量によっても悪化します。
したがって、最高のパフォーマンスを得るには、ループの外で変数を宣言することをお勧めします。または、変数をインラインで宣言します。例を参照してください。
// inline
for (var ai = 0, al = 100000000, av; ai < al; ai++) {
av = av + 1;
}
// outside
var bv;
var bl = 100000000;
for (var bi = 0; bi < bl; bi++) {
bv = bv + 1;
}
変数 'al'と 'av'がforループ宣言行にあることに注意してください。このインライン宣言により、一貫してパフォーマンスが向上しました。ループの外側の変数の宣言についてもです。ここでも、パフォーマンスの違いはほんのわずかです。