Reputation: 191
I'm making a pretty simple game just for fun/practice but I still want to code it well regardless of how simple it is now, in case I want to come back to it and just to learn
So, in that context, my question is:
How much overhead is involved in object allocation? And how well does the interpreter already optimize this? I'm going to be repeatedly checking object grid positions, and if they are still in the same grid square, then no updating the grid array
if (obj.gridPos==obj.getCurrentGridPos()){
//etc
}
But, should I keep an outer "work" point object that the getCurrentGridPos()
changes each time or should it return a new point object each time?
Basically, even if the overhead of creating a point object isnt all that much to matter in this scenario, which is faster?
EDIT: this? which will get called every object each frame
function getGridPos(x,y){
return new Point(Math.ceil(x/25),Math.ceil(y/25));
}
or
//outside the frame by frame update function looping through every object each frame
tempPoint= new Point()
//and each object each frame calls this, passing in tempPoint and checking that value
function makeGridPos(pt,x,y){
pt.x = Math.ceil(x/25);
pt.y = Math.ceil(y/25);
}
Upvotes: 0
Views: 500
Reputation: 707766
Between your two code examples that you have now added, I know of no case where the first would be more efficient than the second. So, if you're trying to optimize for performance or memory use, then re-using an existing object will likely be more efficient than creating a new object each time you call the function.
Note: since JS refers to object by reference, you will have to make sure that your code is not elsewhere hanging on to that object and expecting it to keep its value.
Prior answer:
In all programming (regardless of how good the optimizer is), you are always better caching a result calculated as a result of accessing several member variables that you are using over and over again in the same function rather than recalling the function that calculates it over and over.
So, if you are calling obj.getCurrentGridPos()
more than once and conditions have not changed such that it might return a different result, then you should cache it's value locally (in any language). This is just good programming.
var currentPos = obj.getCurrentGridPos();
And, then use that locally cached value:
if (obj.gridPos == currentPos) {
The interpreter may not be able to do this type of optimization for you because it may not be able to tell whether other operations might cause obj.getCurrentGridPos()
to return something different from one call to another, but you the programmer can know that.
One other thing. If obj.getCurrentGridPos()
returns an actual object, then you probably don't want to be using ==
or ===
to compare objects. That compares ONLY to see if they are literally the same object - it does not compare to see if the two objects have the same properties.
Upvotes: 1
Reputation: 3842
The short answer is to set one current position
object and check against itself as you're literally going to use more memory if you create a new object every time you call getCurrentGridPos()
.
There may be a better place for the is this a new position
check since you should only do that check once per iteration.
It seems optimal to set the currentGridPos
using a RequestAnimationFrame and check against its current x y z
positions before updating it so you can then trigger a changedPosition
type event.
var currentPos = {
x:0,
y:0,
z:0
}
window.requestAnimationFrame(function(newPos){
if (currentPos.x != currentPos.x || currentPos.y != currentPos.y || currentPos.z != newPos.z) {
$.publish("positionChanged"); // tinypubsub https://gist.github.com/661855
}
})
So, just to be clear, yes I think you should keep an outer "work" point object that updates every iteration... and while it's updating you could check to see if its position has changed - this would be a more intentful way to organize the logic and ensure you don't call getCurrentPos
more than once per iteration.
Upvotes: 0
Reputation: 414
It's my understanding that garbage collection stops execution on most JS engines. If you're going to be making many objects per iteration through your game loop and letting them go out of scope that will cause slowdown when the garbage collector takes over.
For this kind of situation you might consider making a singleton to pool your objects with a method to recycle them for reuse by deleting all of their properties, resetting their __proto__
to Object.prototype
, and storing them in an array. You can then request recycled objects from the pool as needed, only increasing the pool size when it runs dry.
Upvotes: 1
Reputation: 2484
This question is VERY difficult to answer because of all the different javascript engine's out there. The "big 4" of browsers all have their own javascript engine/interpreter and each one is going to do their allocation, caching, GCing, etc.. differently.
The Chrome (and Safari) dev tools have a profiling tab where you can profile memory allocation, timings, etc of your code. This will be a place to start (at least for Chrome and Safari)
I'm not certain if IE or Firefox offer such tools, but I wouldn't be surprised if some third party tools exist for these browsers for testing such things...
Also, for reference -
Upvotes: 1