:: KBs ::

String Concatenation

Created Date: 4/23/2008
Last Modified Date: 4/23/2008
Concatenating strings is one of the most common tasks for all software development. This process takes two or more strings and brings them together into one single string. The question that is often asked is “what is the best way of doing this?”

There are many different ways of handling string concatenation in .Net. The best way depends on many different parameters such as string size, number of items to concatenate and the period of time the items will need to be concatenated.

In C# and VB.Net there are many different ways of performing basic string concatenations. C# allows you to use String.Concat or the + operator while in VB.Net you can use String.Concat, the plus (+) operator, or the ampersand (&) operator. Which of these is the most effective?

In C# we can run a couple of tests in order to test which is the best selection. In order to fully test this multiple tests will be needed. Not only will a test be needed for the different operators, but a test will also be needed for different amount of items being concatenated together. Also, in order to get an accurate test the code will be compiled and the results will be pulled using Reflector.Net. This application is used to read the IL and see how it would look in multiple languages.

The first item is to test how three items will be concatenated together. This is the following code that was used for the comparison in C#.

String.Concat Base Test
public String StringConcat1a(String a, String b, String c)
{
String Output = String.Concat(a, b, c);
return Output;
}

public String StringConcat2a(String a, String b, String c)
{
String Output = a + b + c;
return Output;
}

.method public hidebysig instance string StringConcat1a(string a, string b, string c) cil managed

{
.maxstack 3
.locals init (
[0] string Output)
L_0000: ldarg.1
L_0001: ldarg.2
L_0002: ldarg.3
L_0003: call string [mscorlib]System.String::Concat(string, string, string)
L_0008: stloc.0
L_0009: ldloc.0
L_000a: ret
}


.method public hidebysig instance string StringConcat2a(string a, string b, string c) cil managed

{
.maxstack 3
.locals init (
[0] string Output)
L_0000: ldarg.1
L_0001: ldarg.2
L_0002: ldarg.3
L_0003: call string [mscorlib]System.String::Concat(string, string, string)
L_0008: stloc.0
L_0009: ldloc.0
L_000a: ret
}


Surprisingly the results were interesting. Even though the methods were different calls, the compiler actually used the same API calls. This is surprising because it shows that the compiler is smart enough to recognize patterns and translate it into the optimum code.
:: Inside the Compiler ::