Recently, I saw some code that looked something like this:
Now, I don't won't get into arguments about how String.Concat() is more performant here. String.Format() allows code to be more easily localized and it is being used for that purpose here. The real problem is that StringBuilder.AppendFormat() should be used instead:
The reason that this is important is because, internally, String.Format() actually creates a StringBuilder and calls StringBuilder.AppendFormat()! String.Format() is implemented like this:
It turns out that the formatting logic is actually implemented in StringBuilder.AppendFormat(). So, the original code actually caused a second StringBuilder to be created when it wasn't needed.
This is also important to know if you are trying to avoid creating a StringBuilder by concatentating strings with String.Format(). For example:
That code will actually create two StringBuilders. So, creating one StringBuilder and using AppendFormat() will be more performent:
I decided to run some performance tests to verify my claims. First, I timed code that demonstrates the very reason that StringBuilder exists:
The above code creates a new string and then concatenates to it inside of a for-loop. This causes two new strings to be created on each pass--one from String.Format() and one from the concatenation. This is woefully inefficient.
Next, I tested the same code modified to use a StringBuilder with String.Format():
Finally, I tested code that uses StringBuilder.AppendFormat() instead of String.Format():
These three methods ran with the following timings:
Obviously, concatenating a string in a loop without using a StringBuilder is amazing inefficient. And, removing the call to String.Format also yields a performance boost.
Next, I tested the following two methods:
These two methods ran with the following timings:
As you can see, it is important to know when to use String.Format and when to use StringBuilder.AppendFormat(). While the performance boosts that can be achieved are fairly small, they are too easy to code.
You can download the performance tests here: StringFormatPerfTest.zip (4.12 KB).
Page rendered at Thursday, September 02, 2010 2:56:20 PM (Pacific Standard Time, UTC-08:00)
If you're interested in learning F#, this is the most comprehensive book available. The text is well written and the examples are instructive. And after all, the author is the inventor of F#.
Because this book provides source code in Standard ML, it's a fantastic resource for learning F#. One bit of warning: this book does not teach classic data structures. While structures such as binomial heaps and red-black trees are presented, it is assumed that the reader already knows and understands them.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.