Monday, April 24, 2006

Memory & performance optimization for today

Originally, whenever a new object was created in the game, the texture for that object was read from disk, and a new Microsoft.DirectX.Direct3d.Texture object was created, using TextureLoader.FromFile(). I realized today that this approach was crazy wasteful.

At any given time, there can be up to 50 bullets on screen. The texture for the bullet is 256 B. In addition, there can be up to around 20 asteroids. The asteroid texture averages 80 KB. So, worst case, we would be using roughly 1600 KB (1.5 MB) of memory, just to hold the textures!

Here is the original code(called every time a game object was created):

protected TileSet GetTileSet(
Device dev,
int rows,
int cols)
{Toggle}
So, every time we created an object, we were reading from disk, and adding more memory, to hold the texture.

Here is the new code, split into two parts:
(Called once per game session)


public static void LoadTexturesFromDisk(
string texturePath,
string searchPattern,
Device dev)
{Toggle}

(Called every time an object is created)


protected TileSet GetTileSet(
Device dev,
int rows,
int cols)
{Toggle}
So, now, we have each texture in memory exactly one time, in a static variable. Each object then references the correct texture, basically by using a pointer, thereby saving both disk IO time, and significant memory space. The maximum texture memory footprint for asteroids and bullets is now ~367.5 KB. The savings aren't as great as you would expect, since there are 9 textures for asteroids (three different sizes, with three different types). Still, the memory requirements are now one quarter of the original.

Pretty good savings, for one new method, and a couple of lines of code.

No comments: