Javascript 为什么这个新代码比我的旧代码慢?
问题 我已经用一些我期望性能更好的新代码替换了一些性能有问题的代码。相反,它的表现更糟。我想了解为什么会这样,这样我就可以使用chrome的V8运行时,而不是反对它 背景 我的代码是一个基于浏览器的游戏。在正常操作期间,函数之间会传递大量xy坐标。我“修复”之前的一个例子如下:Javascript 为什么这个新代码比我的旧代码慢?,javascript,google-chrome,optimization,garbage-collection,v8,Javascript,Google Chrome,Optimization,Garbage Collection,V8,问题 我已经用一些我期望性能更好的新代码替换了一些性能有问题的代码。相反,它的表现更糟。我想了解为什么会这样,这样我就可以使用chrome的V8运行时,而不是反对它 背景 我的代码是一个基于浏览器的游戏。在正常操作期间,函数之间会传递大量xy坐标。我“修复”之前的一个例子如下: function doSomething1(x,y) { /* Do work here */ return {x: newx, y: newy}; } function doSomething2(x,
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上,旧代码托管在互联网上时,它的运行速度只会变慢。这很奇怪,但不是同一个问题。我将在你写作时结束这个问题。
out[0] = newx
V8只知道分配一个带有“0”字段的新对象,并将newx
粘贴到其中。当你继续
out[1] = newy
它必须跟踪刚刚分配的对象,并为“1”字段分配更多空间。这比{x:newx,y:newy}
昂贵得多,因为在后一种情况下,V8已经知道将有多少字段
我对优化javascript或你的游戏不太了解,所以我很难提出进一步的建议。希望您已经研究了算法问题,现在正在尝试进行一些微调——算法是可以进行重大改进的地方。一个可能的原因是您使用了具有动态大小的“out”数组。你能尝试创建一个固定大小的数组并告诉我们结果吗:)另外你还没有提到你有多少元素,你能添加这个信息吗?“过早优化是万恶之源”—Donald Knuth