3

質問

パフォーマンスの問題が発生していたコードを、パフォーマンスが向上すると予想していた新しいコードに置き換えました。むしろパフォーマンスが悪かった。なぜこれが当てはまるのかを理解したいので、クロムのV8ランタイムに反対するのではなく、それを扱うことができます。

背景

私のコードはブラウザベースのゲーム用です。通常の操作では、多くの xy 座標が関数間でやり取りされます。「修正」する前の例は次のようになります。

function doSomething1(x,y) {
    /* Do work here */
    return {x: newx, y: newy};
}

function doSomething2(x,y) {
    /* Do work here */
    return {x: newx, y: newy};
}

function doSomething3(x, y) {
    var result1 = doSomething1(x, y);
    var result2 = doSomething2(result1.x, result1.y);

    /* Do work here */
    return {x: newx, y: newy};
}

多くの関数が相互に呼び出し、xy プロパティを持つ小さな匿名オブジェクトを返し、それらから値を取り出します。

ゲームを実行すると、ガベージ コレクションの問題が発生します。メモリ グラフは非常にスパイクが多く、フレーム レートは滑らかではありません。これを軽減するために、次のパターンに従うようにコードを書き直すことにしました。

function doSomething(x,y,out) {
    /* Do work here */
    out[0] = newx;
    out[1] = newx;
}

var xy = [0,0]; /* Some 2-length array for results */
doSomething(5,6,xy);
/* 'Return' value in xy */

このように、「割り当て」は 1 つだけであり、配列内の値はチェーンの関数を呼び出すときに置き換えられます。

これは確かに、メモリ割り当てグラフを滑らかにする効果がありました。また、フレーム レートが 50% 低下するという予期しない副作用もありました。

なぜこれが必要なのですか?回避している可能性のある最適化はどのようなものですか? V8 ランタイムで動作するようにこのコードをより適切に記述するにはどうすればよいですか?

アップデート

さらに調査したところ、実際にはコードが 50% 遅くなったわけではないことがわかりました。新しいコードが 127.0.0.1 でホストされ、古いコードがインターネットでホストされている場合にのみ遅くなりました。これは奇妙ですが、同じ質問ではありません。この質問は締め切らせていただきます。

4

1 に答える 1

0

あなたが書くとき

out[0] = newx

V8 は、「0」フィールドを使用して新しいオブジェクトを割り当て、それに固執newxすることしか知りません。続けると

out[1] = newy

割り当てたばかりのオブジェクトを追跡し、「1」フィールドにさらにスペースを割り当てる必要があります。{x: newx, y:newy}後者の場合、V8 はフィールドがいくつになるかをすでに知っているため、これははるかにコストがかかります。

私は JavaScript やゲームの最適化についてよく知らないので、これ以上のアドバイスをするのは難しいです. うまくいけば、あなたはすでにアルゴリズムの問​​題を調べており、微調整をしようとしているだけです.アルゴリズムは大きな改善が可能な場所です.

于 2013-02-28T19:12:51.710 に答える