Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does string concatenation use StringBuilder internally?

Three of my coworkers just told me that there's no reason to use a StringBuilder in place of concatenation using the + operator. In other words, this is fine to do with a bunch of strings: myString1 + myString2 + myString3 + myString4 + mySt...

The rationale that they used was that since .NET 2, the C# compiler will build the same IL if you use the + operator as if you used a StringBuilder.

This is news to me. Are they correct?

like image 306
JamesBrownIsDead Avatar asked May 20 '10 19:05

JamesBrownIsDead


People also ask

How does string concatenation work internally?

String concatenation using StringBuilder class It is mutable class which means values stored in StringBuilder objects can be updated or changed. In the above code snippet, s1, s2 and s are declared as objects of StringBuilder class. s stores the result of concatenation of s1 and s2 using append() method.

Does string format use StringBuilder?

To concatenate String we often use StringBuilder instead of String + String , but also we can do the same with String. format which returns the formatted string by given locale, format and arguments. In performance, is String.

Can we concatenate string and StringBuilder in Java?

StringBuilder is a widely used and recommended way to concatenate two strings in Java. It is mutable, unlike string, meaning that we can change the value of the object.

What method is used to concatenate a string to a StringBuilder object?

append() method is used to append the string representation of some argument to the sequence.


2 Answers

No, they are not correct. String concatenation creates a new string whereas StringBuilder uses a variable size buffer to build the string, only creating a string object when ToString() is called.

There are many discussions on string concatenation techniques all over the Internet if you would like to read further on the subject. Most focus on the efficiency of the different methods when used in loops. In that scenario, StringBuilder is faster over string concatenation using string operators for concatenations of 10 or more strings, which should indicate that it must be using a different method than the concatenation.

That said, if you're concatenating constant string values, the string operators will be better because the compiler will factor them away, and if your performing non-looped concatenation, using the operators will be better as they should result in a single call to string.Concat.

like image 142
Jeff Yates Avatar answered Sep 18 '22 18:09

Jeff Yates


No they are not correct, it won't produce the same IL:

static string StringBuilder()
{
    var s1 = "s1";
    var s2 = "s2";
    var s3 = "s3";
    var s4 = "s4";
    var sb = new StringBuilder();
    sb.Append(s1).Append(s2).Append(s3).Append(s4);
    return sb.ToString();
}

static string Concat()
{
    var s1 = "s1";
    var s2 = "s2";
    var s3 = "s3";
    var s4 = "s4";
    return s1 + s2 + s3 + s4;
}

IL of StringBuilder:

.method private hidebysig static string StringBuilder() cil managed
{
    .maxstack 2
    .locals init (
        [0] string s1,
        [1] string s2,
        [2] string s3,
        [3] string s4,
        [4] class [mscorlib]System.Text.StringBuilder sb)
    L_0000: ldstr "s1"
    L_0005: stloc.0 
    L_0006: ldstr "s2"
    L_000b: stloc.1 
    L_000c: ldstr "s3"
    L_0011: stloc.2 
    L_0012: ldstr "s4"
    L_0017: stloc.3 
    L_0018: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
    L_001d: stloc.s sb
    L_001f: ldloc.s sb
    L_0021: ldloc.0 
    L_0022: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
    L_0027: ldloc.1 
    L_0028: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
    L_002d: ldloc.2 
    L_002e: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
    L_0033: ldloc.3 
    L_0034: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
    L_0039: pop 
    L_003a: ldloc.s sb
    L_003c: callvirt instance string [mscorlib]System.Object::ToString()
    L_0041: ret 
}

IL of Concat:

.method private hidebysig static string Concat() cil managed
{
    .maxstack 4
    .locals init (
        [0] string s1,
        [1] string s2,
        [2] string s3,
        [3] string s4)
    L_0000: ldstr "s1"
    L_0005: stloc.0 
    L_0006: ldstr "s2"
    L_000b: stloc.1 
    L_000c: ldstr "s3"
    L_0011: stloc.2 
    L_0012: ldstr "s4"
    L_0017: stloc.3 
    L_0018: ldloc.0 
    L_0019: ldloc.1 
    L_001a: ldloc.2 
    L_001b: ldloc.3 
    L_001c: call string [mscorlib]System.String::Concat(string, string, string, string)
    L_0021: ret 
}

Also you might find this article interesting.

like image 44
Darin Dimitrov Avatar answered Sep 19 '22 18:09

Darin Dimitrov