Speed Test: String Concatenation
C# and the .NET framework provide several ways in which strings may be concatenated by appending the contents of one string to those of another. Some methods use immutable strings directly, others use mutable data to achieve faster performance.
This test was designed to compare the execution time several of the ways that the C# programming language and the .NET framework provide to enable strings to be concatenated. As strings are immutable, combining two strings creates a third string, which must be initialised and allocated some memory. If you are performing concatenation within a loop, as the number of concatenation operations grows, the number of string references also increases.
The StringBuilder class claims to remove these problems and increase performance. The performance tests described in this article put this claim to the test and attempt to compare the relative times of the string concatenation operator (+), the String.Concat method and the Append method of the StringBuilder class.
Test Process Functionality
It was important that the speed tests for the three concatenation operations each gave the same end result. In each test a string was created by repeatedly appending a single character to an existing value. In the case of the StringBuilder, this was achieved by appending a single character to the StringBuilder instance. Additionally, the StringBuilder was converted to a string at the end of the operation, so the results were all of the same type.
The results were expected to be different depending upon the number of concatenations performed. For this reason, each operation was performed once, to give a result containing two characters, five times, fifty times, five hundred times and one hundred thousand times. This gave a total of fifteen tests.
The timing of the tests was controlled automatically using the Stopwatch class. All of the tests were performed at least one hundred times and the mean average of the results calculated.
The test results included below are those produced using an AMD Athlon64 X2 dual core processor running at 1.9GHz with 4GB RAM. These tests are indicative of further relative test results that were carried out on a variety of equipment
The tests were executed using two operating systems, each with the latest service packs and patches. These were:
- Windows Vista Home Premium
- Windows 7 Enterprise
In each test, the software was compiled as a .NET framework 4.0 console application. All non-essential services were stopped to limit the risk of interference.
This table shows the average timings for the three operations. The five numeric columns show the average times for 1, 5, 50, 500 and 100,000 concatenations. Note that the first four columns show results measured in microseconds. The final column, where 100,000 characters were combined, is shown in milliseconds so should be multiplied by one thousand for comparison with the values for a lower number of iterations.
The results shows that when combining two strings for a simple operation, the string concatenation operator and the String.Concat method give similar performance. The StringBuilder is slightly slower, which can be explained by the additional activity required to instantiate the StringBuilder and to convert the final result to a string.
For five separate operations within a loop, the performance of all three methods is comparable, with the StringBuilder being marginally faster in this test. As the number of concatenations grows larger, the StringBuilder's performance advantage is much clearer. In this test the StringBuilder was approximately three times faster than the other methods for 50 concatenations, twenty times faster for 500 operations and many orders of magnitude faster as the number of iterations increased to 100,000.
These results suggest that for small concatenation operations you could use any of the three methods, picking the one that provides the most readable source code. When you are performing multiple concatenations, especially when you cannot predict how many strings will be combined, you should use the StringBuilder class.
A Note on String.Concat
The above tests are specific to performing multiple concatenation operations within a loop. This is important as some overloads of the String.Concat method allow multiple strings to be supplied and concatenated in a single operation. This is much faster than when calling the Concat method repeatedly. On the test hardware it was found that using String.Concat to combine the strings from an existing array was closer in speed to the same operation in a loop using StringBuilder.Append. The following table shows the average results for a loop containing a number of calls to StringBuilder.Append and a single call to String.Concat passing a string array to achieve the same result.
|Concatenation Operations / Array Length|
A Final Note
The tests performed to achieve the results shown above are unlikely to be replicated in most scenarios. The functionality of your own software may be quite different and lead to different results. If you find that the concatenation method that you use is causing a performance problem you should try all available methods and measure the performance in order to achieve the best results. If you are not experiencing a performance problem, you should choose the method that gives the most readable and maintainable source code.
29 August 2011