I like to write declarative code and C# is very good at it, which is kind of evil if you ask me. In imperative languages you write code that describes how things have to be done. In declarative languages you write code that describes what's to be done no matter how, which basically means: the more you move away from imperative towards declarative, the more you allow your programming language, run-time or compiler do things its way, not yours.
In the case of Mono for Unity, letting it to do things its way will result in hundreds of thousands of little memory allocations, which is not a big deal since allocating memory on these platforms is really cheap, The problem is that this massive amount of allocations causes the garbage collector to kick-in quite often. While garbage collection is not a bad thing in itself, it's definitely something you want to avoid at all costs in FPS-sensitive games.
There are three main sources of declarative awesomeness that will feed the garbage collector heavily:
1. Closures
/// <summary> /// Turning a closure into an anonymous function /// </summary> public void DoSomething( string _name ) { // this will capture the parameter _name, thus creating an object Closure( () => _name ); // this version will 'capture' _name as a parameter, // thus turning the closure into a mere local anonymous function ClosureNOT( _name, _n => _n ); } public void Closure( Func<string> _getStrFn ) { var str = _getStrFn(); // ... } public void ClosureNOT( string _str, Func<string, string> _getStrFn ) { var str = _getStrFn( _str ); // ... }
2. The 'foreach' keyword
It's hard to imagine how much evil is hidden under this keyword. Unless the underlying type is known at compile time to be an array, two things will happen:
-Due to a bug, each call to foreach (not every iteration!) will cause the returned Enumerator object
to be boxed, thus eating 24 bytes of memory in the way. This is an ancient known bug but it's still not fixed in Unity 4.6
-For every iteration, the 'MoveNext()' function is called, which performs some kind of validation. A lot of people will argue that this is not an issue, but in my case, using iterators within high-frequency functions (which is quite common in video-games) will kill the frame rate.
3. LINQ:
If you want to be safe, try to stay away from the declarative part of C# and just make your sensible code look like C++.