简体   繁体   中英

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.

The background

My code is for a browser-based game. During normal operation, lots of xy coordinates are passed around between functions. 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.

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%!!

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?

Update

Further investigation showed that the code was not in fact 50% slower. It was only slower when the new code was hosted on 127.0.0.1 and the old code on the internet. 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. 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. 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.

I don't know a lot about optimizing javascript or your game, so it's hard for me to make further recommendations. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM