Saturday, May 4, 2013

C++ vs C#: Productivity

In my previous post, I compared the performance of C++ and C# for game engines, based on a simple app I wrote that does some basic 3D rendering.  I found C++ to be more than twice as fast as C# for the number crunching and rendering that a game engine has to do.  I thought (and still think months later after making that decision) that switching from C# to C++ was worth it for the gains in runtime performance.

But what about productivity?  C# is more productive in that it takes less time to implement new functionality than it does in C++.  There are a few reasons for this increased productivity:

  1. C# has extensive built-in libraries.  C++'s STL isn't anywhere close.
  2. C#'s syntax is more concise: each class method exists in 1 place (.cs), instead of 2 (.h, .cc).
  3. C# works more consistently across platforms.
  4. C# compiles much more quickly.
  5. C# has a built-in memory manager with garbage collection.
The first 4 of those are things I've run into first hand.  The fifth is the most commonly offered reason, but it doesn't apply to games or other high-performance software.  I'll talk about each of these in order.

1. Built-in Libraries

While C++ has very little built-in, there are a tremendous number of free libraries and example code on the internet for pretty much everything you will ever need.  It's faster to just go to one place for documentation than to google everything; and it's faster to just add a reference to an existing assembly than to find, download, compile, and link against a new 3rd party library.  But while the cost of doing this in C++ is a lot higher than C#, that cost is amortized over time, because incorporating new code into my code is an infrequent task.

There are software industries where gluing together existing technologies in new ways is how things are done, and high level languages really excel at that.  But the time I spend building the core technology in my business is mostly just writing code, not gluing things together.

2. More Concise

The duplication of so much code (99% of method protoypes) is a weakness of C++.  But a good editor eases this pain tremendously.  With a push of a button, I can switch between .cc and .h files.  I can add a new method to a .h file, push a couple buttons, and then a stub is in my .cc file where I just have to write the implementation.  C++ code can be pretty ugly at times, but that's also mitigated by getting used to it.

(Editor features like snippets and macros also help reduce time spent typing in all languages.)

3. Cross Platform Consistency

Developing a cross platform application is more than just compiling and running code on each platform.  Using C# and mono makes developing for all PC platforms (Windows, Mac, Linux) quite easy, but it doesn't help as much with Android and iOS (the application lifetime and interface methods are completely different).

4. Compilation Speed

C# pretty much always compiles faster than C++.  It doesn't really matter how many C# files I change, the app pops up almost instantly.  C++ has to recompile every file I changed and all files that include them, and then relink the whole application.  For small changes, that happens almost instantly; and really, the most painful rebuilds are ones where I change headers that are included everywhere, and those are infrequent.

5. Garbage Collection

When I first switched from C++ to C#, I was excited by the prospect of no longer having to think about memory management.  But it didn't take long for me to learn that it wasn't true.  For games especially, I found that I have to still think about when things will be freed (garbage collection isn't free) and to make sure I null out references so that they will be collected properly.  Having a garbage collector just means than I have to juggle memory differently.  I still have to think every time I type "new" and whenever I store a reference to an object and whenever I subscribe to an event, etc.


C# is certainly more productive than C++, but I'm finding that the difference isn't that big.  I still spend much more time thinking about how to solve problems than about how to implement the solutions.

What makes a language higher level isn't magic: it's abstractions.  The features and libraries that make C# so productive can often be (or have been) duplicated in C++ (like events and delegates, containers, and many algorithms).  Some things can't be duplicated, and that's just part of the cost of using C++ instead.