3

问题

我已经用一些我期望性能更好的新代码替换了一些我遇到性能问题的代码。相反,它的表现更差。我想了解为什么会这样,以便我可以使用 chrome 的 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 */

这样,只有一个“分配”,并且数组中的值在它调用链中的函数时被替换。

这确实具有平滑内存分配图的效果。它还具有将我的帧速率降低 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 回答