Efficient coding in C#

Started by
4 comments, last by Nypyren 11 years, 10 months ago
I've been working on a game engine using C# and SlimDX for about a week now. I only really worked with one entity in the world for a while, until today. I then realized that my engine is incredibly inefficient and really needs a rewrite. I am fine with this.

The most likely reason for my poor performance is my heavy reliance on lots and lots of .Net classes, especially dictionaries and lists, to manage everything. I usually end up creating a ton every step, and that's a no-go. So when I'm writing my new engine, how can I stop myself from making too many unnecessary objects? If it really comes down to trying to thwart the garbage collector, I'm up for switching over to C++ and doing manual memory management.

"So there you have it, ladies and gentlemen: the only API I’ve ever used that requires both elevated privileges and a dedicated user thread just to copy a block of structures from the kernel to the user." - Casey Muratori

boreal.aggydaggy.com

Advertisement
Generally, if you can avoid calling "new" a lot, you should be OK, up to a certain point. It really depends on how much computation you're trying to push through the pipe.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Allocate up front pools, use struct for value types?
Im using C# and SlimDX, and I can tell you (from my experience) that 95%of your performance issues have nothing to do with managed code, and memory management. Mostly it is algorithm / and data-flow design that slows the performance. I have not once in the few years I've been programming reached any kind of limit due to C#'s innate performance. Always, if my framerate starts dropping it's because of my code. Physics is a great example, if you don't use broad-phase, it has an incredible impact on performance. For graphics, passing textures/blendmaps/tilemaps/lightmaps to the card every frame will kill performance. I have forgotten this repeatedly, and Shawn Hargreaves and others have really impressed upon me the importance of letting your gfx card do the work for you.


ApochPiQ mentioned pushing data through the pipe as an issue. That could be something, if you've got a massive terrain, maybe it's too massive, maybe you should do some cpu culling or use the pipelines culling facilites.

It's hard to talk about your particular issues, because you haven't given us much information.

I have a slimDXFramework libary, and a UserInterface library both from which I inherit all sorts of classes as I am constantly striving to build a general purpose code base from which I can inherit all my functionality. Perhaps of relevance to what you have said, my UI library has lists for controls and containers, my ResourceServer uses a dictionary but then it is only ever fetched from when resources are built into UI / game classes. Those things don't concern me as far as performance is concerned. What concerns me is size and complexity of my pixel shaders, whether my resources can be kept in graphics mem to reduce transfer costs, geometry culling & spacial partitioning. When you start looking at these issues (and others) you'll be making savings of 20 to 500% in ur rendertimes so it kinda makes the 5% overhead of memory management look kinda inconsiquential. You say are trying to thwart the garbage collector ? I hardly ever think about the garbage collector, except to casually think on object lifetime. After all, most of your objects should remain unchanged from frame to frame. So why would you be recreating objects all the time ? For advise on how we can help you prevent this practice, example code would really help.

If you haven't done it already, I absolutetly recommend that you build yourself a clock class and do a sweep of your program to time function calls (or use some kinda performance tool). This will pinpoint where your performance issues are and we can start talking about specifics.
Profile, either the quick and dirty way with timers, or with some profiling tool. This should always be the first step of optimizing. Never assume you know where inefficiences are, even fairly experienced coders can be mistaken.
Garbage accumulation and collection is not typically something you should worry about on modern desktops (.Net and Mono both have very good garbage colectors). For other platforms like 360 or WP7 which are much tighter on resources and more limited GCs, it might be worth investigating.

(That's assuming you aren't doing anything crazy like copying a List<T> with 400,000 items in it on each frame...)

Educated guesses are still just guesses! Get a profiler and profile your app! A profiler will show you hard facts.

- There are free profilers for .Net that are pretty painless to use (CLR Profiler).
- There are free profilers for analyzing GPU apps (Intel Graphics Performance Analyzer).

This topic is closed to new replies.

Advertisement