4

かなり複雑な質問があります:)

現在、html5 キャンバス ゲームに取り組んでいます。ゲームのマップに固有の変数は、ゲーム エンジン (engine.js と呼びましょう) とは別のファイル (game.js と呼びましょう) にあります。

グローバル変数は、ローカル変数よりも JS で使用するのが遅いと読みました。したがって、game.js では、ゲーム固有の変数をすべて含むグローバル変数を作成します。engine.js で、このグローバル オブジェクトをローカル変数にコピーし、そこでこのグローバル オブジェクトを削除します。

これは機能しています。しかし、オブジェクトの割り当てはこれらのオブジェクトへの参照のみを渡すことを知っています。

したがって、私の質問は次のとおりです。初期化の最後にグローバル オブジェクトを削除すると、engine.js ですべての変数をローカル変数として直接宣言したかのように、パフォーマンスが低下しますか。 engine.js のローカル変数は、グローバル オブジェクトへの単なる参照でしたか?

すべての変数を engine.js でローカルとして宣言することもできますが、後で他のマップやゲームを作成したい場合に、マップに固有のものを分離すると便利です。

例えば:

game.js:

Game = function() {
this.x = 16;
this.y = 16;
this.myObject = {"test": "hello", "action": "none"};
}
game = new Game();

engine.js: //...

var x = game.x;
var y = game.y;
var obj = {"test": game.myObject.test, "action": game.myObject.action};

//...

この例では、x、y、および obj のパフォーマンスは、ローカル変数と同じくらい速くなりますか、それとも遅くなりますか?

注: グローバル変数とローカル変数のパフォーマンスの違いを実際に確認したわけではありませんが、それについて読んだことは正しいと思います。

私の質問が十分に明確でばかげていないことを願っています:)何かアイデアがあれば...ありがとう!

4

2 に答える 2

2

あなたが話しているパフォーマンスの違いの理由は、javascript が変数の名前をそれが参照する値に解決する方法にあります。したがって、(ごくわずかな) タイムラグは、javascriptが変数を検索した結果です。何かへの参照によって何かが割り当てられる場合、それは名前ではなくメモリ内の実際の値を参照しています。

たとえば、infoの値で呼び出される JavaScript 変数があるとします{ question: null, answer: 42 }。あなたが課題を作るとしたら

info2 = info;

あなたは今すぐその値を見つけて、参照するときにそれを使用するようにjavascriptに指示していますinfo2。現在、infoとの両方が同じ値(同じメモリ アドレス)info2を指しています。を使用するたびに参照を検索してその値を取得するようにjavascriptに指示していませ。これは、グローバル変数参照を 1 回しか検索していないため、この方法で問題がないことを意味します。infoinfo2

JavaScript は、非定数の参照によってのみ割り当てられることに注意してください。

var a = 1;
var b = a;
var a = 2;
var b === 1; // => true

var z = { a: 1 };
var y = z;
z.a = 2;
y.a === 2; // => true

プリミティブ値は定数ですが、オブジェクトはそうではありません。

于 2011-10-04T15:57:53.027 に答える
2

最新のブラウザーでは、おそらくローカル変数とグローバル変数の間にパフォーマンスの違いはほとんどありません。

ただし、メモリ消費には問題があります。グローバル変数は、ページが開いている限り保持されますが、ローカル変数は、コントロールがスコープを離れた後にガベージ コレクションされます。ローカル変数を使用すると、メモリ リークが発生する可能性が低くなります。

アップデート

コメント スレッドでの長い議論の結果、テスト スクリプトを作成して、グローバル スコープ アクセスとローカル スコープ アクセスの実行速度の違いを測定するようになりました。

最初は違いがないように見え、結果はさまざまで、どちらか一方に特定の好みはありませんでした. ただし、@DaveNewton は、ローカル変数のパフォーマンスが桁違いに優れていることを一貫して示す反例を提供しました。


Firefox 7

20000 回のグローバル アクセスに使用されたミリ秒: 132

20000 ローカル アクセスに使用されるミリ秒: 159

Internet Explorer9

20000 回のグローバル アクセスに使用されるミリ秒: 1750

20000 ローカル アクセスに使用されるミリ秒: 1699

Google Chrome 14

20000 回のグローバル アクセスに使用されたミリ秒: 46

20000 ローカル アクセスに使用されるミリ秒: 55

テストスクリプト自体

<html>
<head>
<script type="text/javascript">

function t() {

var test = function () {}
test.issue = new String("hello");

var start = new Date().getTime();
(function() {
    (function() {
        (function() {
            (function() {
                (function() {
                    (function() {
                        (function() {
                            var a = document.getElementById("a");
                            for (var i = 0; i < 20000; i++) {
                                a.innerHTML = test.issue.toString();
                            }
                            a = null;
                        })();
                    })();
                })();
            })();
        })();
    })();
})();
var stop = new Date().getTime();
document.getElementById("a").innerHTML = "Milliseconds used for 20000 global accesses: " + (stop - start);


var start = new Date().getTime();
(function() {
    (function() {
        (function() {
            (function() {
                (function() {
                    (function() {
                        (function() {
                            var c = document.getElementById("c");
                            var testx = {};
                            testx.issue = new String("hello");
                            for (var i = 0; i < 20000; i++) {
                                c.innerHTML = testx.issue.toString();
                            }
                            c = null;
                        })();
                    })();
                })();
            })();
        })();
    })();
})();
var stop = new Date().getTime();
document.getElementById("c").innerHTML = "Milliseconds used for 20000 local accesses: " + (stop - start);

}

window.onload = function () {
    document.getElementById('b').onclick = t;
}

</script>
</head>
<body>
<div align="center"><button id="b">Run Test</button></div>
<div id="a"></div>
<div id="c"></div>
</body>

</html>

ローカル変数へのより高速なアクセスを示す反例。

var t0 = new Date();
var i; 
for (i=0; i<10000000; i++); 
var t1 = new Date(); 
function count() { for (var i=0; i<10000000; i++); } 
var t2 = new Date(); 
count(); 
var t3 = new Date(); 
d = document; 
d.write('Without local variables = ', t1-t0, '<br />'); 
d.write('With local variables = ', t3-t2, '<br />');
于 2011-10-04T15:24:35.597 に答える