I have a function for applying gravity forces between every possible pair of bodies on my game. It is the most used function, and can run more than 100k times per frame so every minor improvement on performance will make a HUGE difference here.
I replaced some divisions by multiplications and the general FPS increased from 5fps to 20fps with ~1000 bodies. This is how performance is affected by this function.
Precision can be decreased if it increases performance considerably. Just make sure you make it clear that a change will decrease precision in your review.
applyGravityBetween(bodyA, bodyB, collisionCallback) {
var distX = bodyB.x - bodyA.x,
distY = bodyB.y - bodyA.y,
distSqr = distX * distX + distY * distY,
forceA, forceB, dist;
if (distSqr > (bodyA.radius + bodyB.radius) * (bodyA.radius + bodyB.radius)) {
// ALERT: Radical actions were taken here to make faster code. Division was avoided at max.
dist = 1 / Math.sqrt(distSqr); // Dividing one by the distance allows us to multiply instead of dividing later when setting actual velocities, which is more performant.
forceA = bodyB.mass * dist * dist;
forceB = bodyA.mass * dist * dist; // Instead of dividing by `distSqr` we can multiply by `dist` twice.
bodyA.vx += forceA * distX * dist;
bodyA.vy += forceA * distY * dist;
bodyB.vx -= forceB * distX * dist;
bodyB.vy -= forceB * distY * dist;
} else if (typeof collisionCallback === "function" && bodyA.collidable && bodyB.collidable) collisionCallback(bodyA, bodyB);
}
EDIT:
Here's a benchmark for each separate piece from this function, so you can focus on what you're going to improve:
var
declarations took 3.199ms
on average to run. Collision check took 3.342ms
. Math.sqrt()
took 3.122ms
.
This question is also related to this one, so if you're interested you can go there too and... Review.
forceA = bodyB.mass * (dist = dist * dist * dist); forceB = bodyA.mass * dist;
\$\endgroup\$(earth, moon)
and(moon, earth)
, does it? I assume you've done all that correctly, but just making sure \$\endgroup\$