Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.87k stars 826 forks source link

Pooling Matrix, Vector.<Number> and VertexData #749

Closed Fraggle closed 8 years ago

Fraggle commented 9 years ago

Hi Daniel,

I am wondering if it could be a good idea to pool theses 3 objects globally in Starling? From my understanding, it would require some overrided dispose() in a few classe to put the objects back into their pool when no longer needed. I'm guessing it could be a really good performance boost because we are creating quite a few of theses frequently. I could do it and provide a patch I think but I dont want to go down that road if you don't think it's a good idea.

So.. what's your opinion ?

PrimaryFeather commented 9 years ago

Hm ... we have to be a little careful with that one. One problem is that many of these objects (at least when used as instance members) are directly accessible, e.g. the "displayObject.transformationMatrix" property or similar ones. It's very dangerous to pool objects that are accessible to the outside, because developers might keep a reference to it, and then that reference is suddenly used by another instance.

I've seen such problems with the "Juggler.tween" and "Juggler.delayCall" methods, even though they only return an "IAnimatable" instead of a Tween / DelayedCall, because I thought that would prevent developers from keeping those objects. But still, some cast them back to the actual classes and then ran into problems when the objects were taken out of the pool later.

The same is true for "VertexData" (although on a less critical level), because it's a protected member of the Quad class. (And the instances that are used during rendering are implicitly pooled anyway, because the QuadBatches are re-used).

Personally, I tend to follow this route: avoid allocations as much as possible in normal methods, e.g. everything that occurs during Starling's render loop / event handling. But when somebody allocates a new object anyway (e.g. new Sprite()), then just live with the allocations that happen subsequently.

After all, if it becomes necessary, people can always pool those instances themselves. That will always achieve the best results, because it happens at a higher level than what we can do with any member variables. (And if they do that, any additional internal pooling becomes useless.)

Does that make any sense?

I know one could argue either way, probably; but anything that might create nasty side-effects should be carefully considered.

PrimaryFeather commented 8 years ago

Starling 2 now contains a Pool class that allows pooling of some basic objects (Point, Vector3D, Rectangle, Matrix), and I'm using that at several places. Any Starling user can access the pool just the same.

Still, I don't use it for class members, since I think it's too dangerous that the object become re-used mistakenly, as described above. That's also the reason why the Juggler class now returns int-handles instead of IAnimatable instances as in v1.x; that proved to be the safest way of doing it.