Mysteries of the .NET Framework
Andrew Hunter has been described as the master of all that is deep and dark in the .NET Framework. In order to write the guts of ANTS 4, he needed to be very familiar with aspects of the framework that the ordinary application programmer wouldn’t need to understand. However, there is one point at which you and Andrew would be interested in the same thing: Tuning applications to make them perform well.
The more you look at .NET performance, the more you hedge your opinion with words like ‘it depends…’. We therefore thought that it would be interesting to focus a discussion on four different .NET performance questions. To make it more interesting, we gave away prizes for the best contributions.
Andrew selected the four questions that deserved interesting answers. These were:
- When processing some data into a list, is it faster to build up a collection and return it as an enumerator, or use yield to create the enumerator ‘on the fly’?
- What is the best approach to doing fast complex string manipulation in .NET?
- What are the differences between a debug and a release build in C#? How do they affect performance?
- When is it a good idea to start using more than one thread?
To make it more interesting, we decided to award a free license to ANTS 4 to the best entries. Andrew Hunter judged the answers, assisted by the usual Simple-Talk distinguished panel of judges, including Phil Factor, Andrew Clarke, Tony Davis and James Moore. You’ll see, if you read the responses, that the questions really struck a chord with our readers.
The winners were, as usual, very close. After a considerable amount of deliberation, Andrew Hunter and the panel came up with the following winners, in order of merit
- Eric Gunn on yield. A well-deserved win
- TheCPUWizard on strings
- Steve S on threads
- Nuno Gomes for his answer on processing a list
- Lewis Moten for spotting some catches with the list question
- Hugh Worm’s analogy deserves something
- ovalsquare for his observations on debugging
- dmajkic for his effort (though there usually isn’t a need to use unmanaged code)
Andrew Hunter writes:
“There was a gotcha in the yield question, which does tie in to the debug builds question as well. If you time code using yield in a debug build you’ll generally find that it runs much slower than it does in a release build, leading to the impression that using an array is faster: this illustrates that it’s not just important to measure the performance of your application, but to make sure that you’re measuring it using the right builds.”
“The debug question essentially had two ways of answering it: from the point of view of what the compiler does differently, or what the run-time itself does differently. The C# compiler will optimise the code when asked to produce a release build, which reduces the size of the resulting file and can result in a performance increase. I say ‘can’ increase performance here because the JIT can legitimately apply the same optimisations, resulting in different IL but the same ultimate performance. Debug builds also have some extra attributes applied to them by the compiler that instructs the JIT to generate code that is easier for a debugger to work with: this is the DebuggableAttribute attribute.”
“One thing we were trying for with the strings question was to illustrate that the right solution for one situation is not necessarily universal. For instance, StringBuilder works very well when building lots of very small strings, but starts to perform poorly as the string size increases. Internally, it stores the string as an array of bytes, so as it grows it has to spend more and more time copying the string around. Eventually the string size will exceed the largest available fragment in the large object heap and it will fail with an OutOfMemoryException: due to the way the heap works, this is usually much smaller than the maximum memory available to the application. Setting the capacity in advance or building the string in fragments is a good way to work around this: TheCPUWizard‘s suggestion was a good way to deal with this issue.”