[英]Why is this new code slower than my old code?
The question 这个问题
I have replaced some code that I was having performance issues with with some new code that I had expected to perform better. 我已经用一些我希望表现更好的新代码替换了一些我遇到性能问题的代码。 Instead, it performed worse.
相反,它表现得更糟。 I'd like to understand why this is the case so that I can work with chrome's V8 runtime rather than against it.
我想了解为什么会这样,以便我可以使用chrome的V8运行时而不是它。
The background 的背景
My code is for a browser-based game. 我的代码是基于浏览器的游戏。 During normal operation, lots of xy coordinates are passed around between functions.
在正常操作期间,许多xy坐标在函数之间传递。 An example of this before I 'fixed' things looked something like this:
在我“修复”事物之前的一个例子看起来像这样:
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};
}
You get the idea.. lots of functions calling each other, returning little anonymous objects with xy properties and plucking values out of them. 你明白了......许多函数互相调用,返回带有xy属性的小匿名对象并从中取出值。
When my game runs, it has garbage collection issues. 当我的游戏运行时,它有垃圾收集问题。 The memory graph is very spikey and the frame rate is not smooth.
内存图非常灵巧,帧速率也不平滑。 To mitigate this, I decided to re-write my code so that it followed this pattern:
为了缓解这种情况,我决定重新编写代码,使其遵循以下模式:
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 */
In this way there is only one 'allocation' and the values are replaced in the array as it calls functions down the chain. 通过这种方式,只有一个“分配”,并且值在数组中被替换,因为它在链中调用函数。
This did indeed have the effect of smoothing off the memory allocation graph. 这确实具有平滑内存分配图的效果。 It also had the unexpected side-effect of reducing my frame rate by 50%!!
它也有意想不到的副作用,将帧率降低50%!!
Why should this be? 为什么会这样? What optimizations are in play that I may be circumventing?
我可能正在绕过哪些优化措施? How can I better write this code to work with the V8 runtime?
如何更好地编写此代码以使用V8运行时?
Update 更新
Further investigation showed that the code was not in fact 50% slower. 进一步调查显示,该代码实际上并没有慢50%。 It was only slower when the new code was hosted on 127.0.0.1 and the old code on the internet.
当新代码托管在127.0.0.1上并且旧代码在互联网上时,它只会慢一些。 This is strange, but is not the same question.
这很奇怪,但不是同一个问题。 I will close this question.
我将结束这个问题。
When you write 当你写作
out[0] = newx
V8 will only know to allocate a new object with the '0' field and stick newx
into it. V8只知道分配一个带有'0'字段的新对象并将
newx
到其中。 When you continue with 当你继续
out[1] = newy
It has to track down the object it just allocated, and allocate more space for the '1' field. 它必须追踪它刚刚分配的对象,并为“1”字段分配更多空间。 This is a lot more expensive than
{x: newx, y:newy}
because in the latter case V8 already knows how many fields there are going to be. 这比
{x: newx, y:newy}
贵得多{x: newx, y:newy}
因为在后一种情况下,V8已经知道将会有多少个字段。
I don't know a lot about optimizing javascript or your game, so it's hard for me to make further recommendations. 我不太了解优化javascript或你的游戏,所以我很难提出进一步的建议。 Hopefully you've already looked at algorithmic issues and are now trying to just do some fine tuning -- the algorithms are where big improvements can be made.
希望你已经看过算法问题,现在正试着做一些微调 - 算法是可以做出重大改进的地方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.