Optimizing Performance On The Xbox 360 - Part 2
In part 1 I described the reasons why Xbox 360 is slower than an equivalent PC and some of the basic recommendations for optimizing C# code to make it run faster. In this post I will mention a few other tricks to increase performance on the Xbox 360.
In the .NET world, objects are allocated on the heap and structures are allocated on the stack. Remember, only the heap is garbage collected, this means that structures are not subject to the expensive garbage collection operation. Allocation on the stack is basically free as we only need to increase a stack pointer and call a constructor. This means you can reduce garbage collection and increase speed by using structures instead of objects – however, you need to know the difference between the two. You should also follow the general recommendations for using structures:
- Small data objects (data containers)
- Often destroyed or created
- Read-only (or mostly-read) objects
Reuse those objects
As mentioned before, objects are allocated on the heap that is garbage collected. That is why you should avoid creating a lot of objects on each update. Instead, you should reuse the objects using pools as explained in part 1. Another and simpler way is to move the object to outer scope and/or make it static. One object that you should pay close attention to is the SpriteBatch (if you are using XNA). Do not create the SpriteBatch object on each update, but keep a reference to it through out the game.
You should also pay attention to List<T>, arrays and other commonly used list types. When you create a new List<T> and add a single item to it, it will initialize an array with a size of 4. If you add more than 4 elements, it will create a new array with double the size. The results is that 2 arrays have been garbage collected. To keep that from happening, you should initialize List<T> with a capacity that is equal to what you need. To keep the List<T> form being garbage collected, you should move the list to outer scope and clear it before use instead of initializing a new instance.
Boxing is the process of encapsulating a value type in a reference type container. This is great as it allows us to pass value types as objects to methods or store them in collections as objects. However, this is not great for performance and we have to eliminate boxing and unboxing where we can. You can use tools like Reflector or Ildasm to disassemble your application to MSIL code. Inside the MSIL code you simply look for the box and unbox keywords. You can find more info along with pictures in my post Performance Tips and Tricks Part 4.