In this final (for now) instalment, let me ask a rhetorical question: Is managed code the right choice for every applications? Absolutely not! For example, .NET and Windows itself are not designed for use in real-time systems. There are no guarentees on worst-case latency during processing. i.e. If you’re writing software for a pacemaker or nuclear reactor – both hard real-time systems since failure results in loss of life – you have deadlines by which you have to complete computations and if you don’t make those deadlines, your system may fail. You might think it trivial to meet a deadline (e.g. worst-case length of computation / instructions per second), but consider the fact that any device connected to the system can raise an interrupt, which can result in your code being preempted so that kernel-level driver code can run. So figuring out worst-case latency involves considering the impact of all connected peripherals (and how they interact) in addition to other factors. Not an easy problem and the reason why there exists many operating systems specifically designed for real-time applications. How much software truly has real-time constraints? Very little, to be honest.
But I digress. I think you get the point that .NET isn’t appropriate for all software, but then again, neither is Java or many other commonly used languages and frameworks. However .NET is applicable to a broader class of software than you might imagine. What surprises many people is that .NET isn’t slower than unmanaged code in many cases. There are a lot of areas, such as raw numerical calculations, where the JITed MSIL code is essentially equivalent to what an optimising C++ compiler would produce. Games, which traditionally try to squeeze out the every last ounce of performance from your hardware, are starting to be written in managed code, and we’re not talking Space Invaders and Pacman. Arena Wars, a real-time strategy game, is built using the .NET Framework 1.1. (I’ve honestly never played this game, but it does go to show you that it is possible to write a real game using managed code.) Games are no longer requiring hand-optimized assembly language for critical loops. (For example, Quake by id Software was written in C with parts in
hand-optimized assembly. Quake 2 was also written in C, but contained
no assembly language. The slight performance gain of using assembly
language was not deemed necessary.)
Look at the performance characteristics of your code. If the bulk of your CPU time is spent in third-party frameworks (like DirectX, a physics engine, or an AI engine), it’s rather irrelevant what you write the code that drives the third-party framework, assuming the overhead of calling it isn’t too high. Imagine a situation where you have a sort and you naively use a bubble sort, which is known to be slow. Should this concern you? That depends on how much time is spent in the sort. If the CPU spends 1% of the overall application time in the bubble sort, speeding it up will result in at most a 1% performance gain. Not worth your time. If however the application spends 50% of its time in the sort, then even a factor of 2 speed-up would result in 25% faster execution. The same is true with the choice between managed and unmanaged code. If the time spent in your code is a small fraction of the overall execution time, it’s rather irrelevant what that code is written in. Pick a language/framework that allows you to develop quickly and with the fewest number of errors. But as I pointed out earlier, managed code doesn’t equate to slow code.
In summary, there are trade-offs in using managed code as there are with any runtime environment. You’re not going to get any faster than hand-optimized assembly (if you have infinite time to optimize), but who is going to write Windows applications in assembly language today? (I’m ignoring Steve Gibson for the moment. Amazing what one can do in assembly language these days, but not somewhere I want to live my developer life personally.) The key is to know your tools and know which ones are right for which job. With that in mind, I leave you with some links comparing managed to unmanaged code performance. I hope that they prove enlightening.