16
votes

I am writing a game using C# 2010 and XNA 4.0. I want it to be a good game and not some "just another crap" and so one of my goals is good framerate. For this I would like to ask you for some advices, be it XNA related or C# related - what can I do to speed up my code and so improve FPS.

Here is some stuff I found out:

  • (c#) using array insted of list<> will improve performance a lot, in case you want to access huge amount of data (or even lots: having an array of 20000 items gave almost 180% FPS of list of 20000.
  • (c#) using for instead of foreach will improve performance. On same 20000 elements it's like 5-10% difference.
  • (xna and c#) calling methods costs performance, so when I scattered my code into methods what called other methods and such, and everything was so cool and object oriented it was on the cost of 1-3 FPS each call.
  • (xna) update vs. draw: it was no difference in performance when I put code into update() and draw(), so if you do not care much, you do not have to put some methods under update() instead of keeping everything together in draw() in hope of better FPS.
  • (xna) no idea if it is me or just 4.0, but when you load a .X with lot of textures in it and pretty complex meshes, it takes a LOT of time to load. I had to write my own .X loader and mesh/model renderer just because XNA started to load texture for each and every triangle regardless if the previous one had the same texture to it. Even writing my own contentloader which caches textures for you is no solution, because it is still utilised a lot of times. If you make something nice and fluffy I suggest using drawuserprimitives and not Model class. (no idea if it is 4.0 only, or 3.1 had such performance problem too)
  • (xna and c#) Try to avoid using "new" when it is about drawing. I saw some code around on web, what was copy/pasted together and had "basicEffect = new BasicEffect(graphicsDevice);" and such uglyness in the draw(), and even worse: in iterations inside draw(). Such will kill performance. Instead of this have one such class in "game" or in a static class. This applies for other "temp-objects" too: ugly but I think it is better to create something global and use it with attention then to make a nice and fluffy code what will make our game because of garbage collector.

Ok, so to make long story short, please post some good advice here, so I / we can make good, fast and optimized games ;)

Thanks in advance: Zéiksz

3
Seems like a good CW candidate :)BlackBear
I'd recommend making this a community wiki.Ben
I don't buy that using a solid OOP architecture costs 1-3 fps each call...Blindy
What does the GC have to do with it? IF you use the same objects you'll allocate the same memory, be it in a single function or not. Functions don't get GC'd.Blindy
I'll note that foreach can use an IEnumerawhatever<> interface depending on the collection and that -can- trigger a GC. But the part about structuring code into methods doesn't make sense. The compiler should inline where appropriate, and you could force it to even if it didn't.Dave

3 Answers

8
votes

Software optimisation is a craft. The best kinds of optimisation are evidence based on collected statistics.

Until you have a problem don't optimise. Don't you think that game playability is more important than this metric or another? My suggestion is make the game first and then consider where it's not performing as you'd like.

Then post some specific questions and I'm sure you'll get some help here on the specific issues.

In the mean time I suggest that you'll get more information from games development books like those listed here : http://forums.create.msdn.com/forums/p/8642/45646.aspx.

XNA Extereme 101 - seems to be an interesting tutorial

8
votes

My 2 cents worth:

Don't put all your code in one method because you think it costs to call a method. If you THINK your losing 1-3 FPS by calling an empty method, You probably haven't finished researching the 1-3 loss yet. For that loss to be true during an empty method call, you'd have to have a FrameRate in the MANY thousands.... where you wouldn't concern yourself about a 1-3 drop.

FPS is a bad way to judge performance in XNA. When you have variable time step enabled, other processes that the OS is involved with can influence your frame rate. You really need to profile instead. Just concentrate on the amount of time it actually takes to complete the Update &/or Draw Methods by timing them with a System.Diagnostic.Stopwatch object. time them individually, not together (very important).

The 'new' keyword should not only be avoided in the draw call but anywhere in both the update & draw... FOR reference types only. Use the new keyword anytime and anywhere you need to with value types.

7
votes

UberGeekGames has a good article on XNA optimization. It's mostly targeted at Xbox and WP7, but many of the things also apply to PC.

http://www.sgtconker.com/2011/05/high-end-performance-optimizations-on-the-xbox-360-and-windows-phone-7/

Original site is dead, but is available in the Internet Archive:

Archived version of High end performance optimizations on the xbox 360 and windows phone7

The rule of thumb is "profile before optimizing".