I’m playing with MonoGame right now, and I was investigating the SpriteBatch.Draw() method.
Inside of the method, which can be called tens of thousands of times per second, I see the following:
public void Draw (Texture2D texture,
Rectangle destinationRectangle,
Rectangle? sourceRectangle,
Color color,
float rotation,
Vector2 origin,
SpriteEffects effect,
float depth)
{
CheckValid(texture);
DrawInternal(texture,
new Vector4(destinationRectangle.X, //<-------------- Oh Noes! :O
destinationRectangle.Y,
destinationRectangle.Width,
destinationRectangle.Height),
sourceRectangle,
color,
rotation,
new Vector2(origin.X * ((float)destinationRectangle.Width (float)texture.Width), <-- Oh Noes!
origin.Y * ((float)destinationRectangle.Height / (float)texture.Height)),
effect,
depth);
}
It would seem that thousands of new vectors are being allocated every 60th of a second or so.
MonoGame is a platform which is meant for (among other things) mobile development. I did some mobile development which ran on Dalvik, and allocating in this manner was never a good idea. On slow mobile processors the build up of objects in need of collection would eventually cause GC to run and cause a noticeable dip in performance (up to 200 milliseconds on some devices). Which leads me to my question:
Is there something about the way the CLR/Mono GC runs, or some other factor, that would prevent this performance hit from occurring, or is MonoGame doing something it shouldn’t in one of its most called functions?
The
Vector4type is not a class, it’s a structure. Creating a new instance of it doesn’t create an object on the heap, it creates a structure value. In this case the value is pushed onto the stack for the method call, so it’s basically the same work as pushing the members as separate parameters.