Back to talking about performance and .NET. Let me give you an example from my own experience regarding skepticism about whether you can write highly performant applications using managed code. The thought is that if it ain’t C++, it can’t be fast. (The same skepticism applies to Java, too.) I can attest first-hand that it is possible to write highly performant applications using .NET. For example, I was brought in to assist with the development of a server application that was written in C++ and having perf problems. The performance goal was 2000 concurrent clients on reasonable hardware. The alpha version in C++ was able to handle 200 concurrent clients and fell over (read the server crashed with out of memory errors) at 500. The team had spent approximately 3 months working on the C++ codebase writing it and trying to bring it up to par. They had never written server software before and had made a few honest mistakes such as firing up a thread per client (which resulted in running out of memory as stack space was allocated for each thread) and writing to the database while a remote connection was held open. (The problem with holding the connection open was that the clients were just dropping off information and didn’t require an ACK. So you’re holding open a TCP socket for an extra 50-100 ms during the synchronous database write and then closing it rather than freeing it up immediately.)
The team believed that you could only write a highly performant server in C++. So they weren’t too keen when I suggested using C# and .NET. With the assistance of another developer, we created in two days a skunkworks prototype in C# that serviced clients using a thread pool and dropping the results into a queue (implemented with MSMQ) so that we didn’t have to roundtrip to the database on every connection. (The results were lazy-loaded into the database by a queue listener.) This allowed us to free up sockets quickly. The results… On the same hardware that was falling over at 500 clients with the C++ version, we did approximately 10,000 clients with little to no perf tuning. (We used the same client load generator in both cases for a fair comparison.)
Why did we use C#? It wasn’t our intent to subvert their development standards. We just wanted to show that this alternate architecture could scale and the most expedient way to implement it was using .NET. When we showed them the managed version, their jaws dropped. When I suggested that we could spend a few weeks (literally!) writing the same thing in C++, the immediate question was “Why bother?” They had spent more time tracking down memory leaks and bad pointer arithmetic in their C++ codebase than we had spent implementing ours. We more than exceeded their performance goals and could implement new features faster. They didn’t look back and implemented a highly scalable server written ground-up in C# and .NET.
Next time, we’ll look at the performance characteristics of different aspects of managed code…