0

私は楽しみ/練習のためだけに非常にシンプルなゲームを作成していますが、戻ってきて学習する場合に備えて、現在のシンプルさに関係なく、適切にコーディングしたいと考えています

したがって、その文脈で、私の質問は次のとおりです。

オブジェクトの割り当てに関係するオーバーヘッドはどれくらいですか? そして、インタープリターはすでにこれをどの程度最適化していますか? オブジェクトのグリッド位置を繰り返しチェックしますが、それらがまだ同じグリッドの正方形にある場合は、グリッド配列を更新しません

if (obj.gridPos==obj.getCurrentGridPos()){
    //etc
}

しかし、毎回変化する外側の「作業」ポイント オブジェクトを保持する必要がありますか、getCurrentGridPos()それとも毎回新しいポイント オブジェクトを返す必要がありますか?

基本的に、このシナリオでは点オブジェクトを作成するオーバーヘッドがそれほど重要ではないとしても、どちらが速いでしょうか?

編集:これ?フレームごとにすべてのオブジェクトが呼び出されます

function getGridPos(x,y){
  return new Point(Math.ceil(x/25),Math.ceil(y/25));
}

また

//outside the frame by frame update function looping through every object each frame
tempPoint= new Point()

//and each object each frame calls this, passing in tempPoint and checking that value
function makeGridPos(pt,x,y){
  pt.x = Math.ceil(x/25);
  pt.y = Math.ceil(y/25);
}
4

4 に答える 4

1

ガベージコレクションはほとんどのJSエンジンで実行を停止することを理解しています。ゲームループの反復ごとに多くのオブジェクトを作成し、それらをスコープ外に置くと、ガベージコレクターが引き継ぐときに速度が低下します。

この種の状況では、オブジェクトをすべて削除し、にリセットして配列に格納することにより、オブジェクトをリサイクルして再利用するメソッドを使用して、オブジェクトをプールするシングルトンを作成することを検討でき__proto__ますObject.prototype。その後、必要に応じてプールにリサイクルオブジェクトをリクエストできますが、プールが枯渇したときにのみプールサイズを大きくします。

于 2012-07-15T17:06:39.353 に答える
1

ここで追加した2つのコード例の間に、最初のコードが2番目のコードよりも効率的である場合はありません。したがって、パフォーマンスやメモリの使用を最適化しようとしている場合は、関数を呼び出すたびに新しいオブジェクトを作成するよりも、既存のオブジェクトを再利用する方が効率的である可能性があります。

注:JSは参照によってオブジェクトを参照するため、コードがそのオブジェクトにぶら下がっていて、その値を保持することを期待していないことを確認する必要があります。


事前回答:

すべてのプログラミング(オプティマイザーがどれほど優れているかに関係なく)では、同じ関数で何度も使用している複数のメンバー変数にアクセスした結果として計算された結果を、それを計算する関数を呼び出すよりも常にキャッシュする方が適切です。オーバー。

したがって、obj.getCurrentGridPos()複数回呼び出していて、異なる結果を返すように条件が変更されていない場合は、その値をローカルに(任意の言語で)キャッシュする必要があります。これはちょうど良いプログラミングです。

var currentPos = obj.getCurrentGridPos();

そして、そのローカルにキャッシュされた値を使用します。

if (obj.gridPos == currentPos) {

obj.getCurrentGridPos()インタープリターは、他の操作によって呼び出しごとに異なるものが返されるかどうかを判断できないため、このタイプの最適化を実行できない場合がありますが、プログラマーはそれを知っています。

もう1つ。実際のオブジェクトを返す場合は、オブジェクトを使用したり、オブジェクトを比較したりしobj.getCurrentGridPos()たくない可能性があります。これは、文字通り同じオブジェクトであるかどうかを確認するためにのみ比較されます。2つのオブジェクトが同じプロパティを持っているかどうかを確認するためには比較されません。=====

于 2012-07-15T17:50:42.420 に答える
1

さまざまな JavaScript エンジンが存在するため、この質問に答えるのは非常に困難です。ブラウザーの「ビッグ 4」はすべて独自の JavaScript エンジン/インタープリターを備えており、それぞれが割り当て、キャッシュ、GC などを異なる方法で実行します。

Chrome (および Safari) 開発ツールには、コードのメモリ割り当て、タイミングなどをプロファイリングできるプロファイリング タブがあります。ここから開始します (少なくとも Chrome と Safari の場合)。

IE や Firefox がそのようなツールを提供しているかどうかは定かではありませんが、そのようなことをテストするためのこれらのブラウザー用のサードパーティ ツールが存在しても驚かないでしょう...

また、参考までに――

  • Chrome は V8 JavaScript エンジンを使用します
  • IE は Triton (まだそう呼ばれていると思いますか?) の JavaScript エンジンを使用します。
  • FirefoxはSpidermonkeyを使用していると思います
  • Safari よくわかりませんが、WebKit に含まれているものを使用していると思います。
于 2012-07-15T17:02:19.823 に答える
0

簡単な答えは、current positionを呼び出すたびに新しいオブジェクトを作成すると、文字通りより多くのメモリを使用するため、1 つのオブジェクトを設定してそれ自体をチェックすることですgetCurrentGridPos()

is this a new position反復ごとに 1 回だけチェックを行う必要がある ため、チェックに適した場所がある可能性があります。

RequestAnimationFramecurrentGridPosを使用してを設定し、更新する前に現在の位置をチェックして、タイプ イベントをトリガーできるようにするのが最適なようです。x y zchangedPosition

var currentPos = {
    x:0,
    y:0,
    z:0
}
window.requestAnimationFrame(function(newPos){
    if (currentPos.x != currentPos.x || currentPos.y != currentPos.y || currentPos.z != newPos.z) {
        $.publish("positionChanged"); // tinypubsub https://gist.github.com/661855
    }
})

したがって、明確にするために、はい、すべての反復を更新する外側の「作業」ポイントオブジェクトを保持する必要があると思います...更新中に、その位置が変更されたかどうかを確認できます-これは、より意図的な方法ですロジックを整理し、getCurrentPos反復ごとに複数回呼び出さないようにします。

于 2012-07-15T17:02:29.420 に答える