Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StringBuilder.Append Vs StringBuilder.AppendFormat

I was wondering about StringBuilder and I've got a question that I was hoping the community would be able to explain.

Let's just forget about code readability, which of these is faster and why?

StringBuilder.Append:

StringBuilder sb = new StringBuilder(); sb.Append(string1); sb.Append("----"); sb.Append(string2); 

StringBuilder.AppendFormat:

StringBuilder sb = new StringBuilder(); sb.AppendFormat("{0}----{1}",string1,string2); 
like image 506
Sergio Avatar asked Apr 02 '09 16:04

Sergio


People also ask

What is AppendFormat?

AppendFormat(IFormatProvider, String, Object) Appends the string returned by processing a composite format string, which contains zero or more format items, to this instance. Each format item is replaced by the string representation of a single argument using a specified format provider.

Is StringBuilder faster than string format?

StringBuilder is faster, because String. format has to parse the format string (a complex domain specific language).

Can you append a StringBuilder to a StringBuilder?

StringBuilder has a public StringBuilder append(CharSequence s) method. StringBuilder implements the CharSequence interface, so you can pass a StringBuilder to that method.

Why is StringBuilder more efficient C#?

Creating and initializing a new object is more expensive than appending a character to an buffer, so that is why string builder is faster, as a general rule, than string concatenation.


2 Answers

It's impossible to say, not knowing the size of string1 and string2.

With the call to AppendFormat, it will preallocate the buffer just once given the length of the format string and the strings that will be inserted and then concatenate everything and insert it into the buffer. For very large strings, this will be advantageous over separate calls to Append which might cause the buffer to expand multiple times.

However, the three calls to Append might or might not trigger growth of the buffer and that check is performed each call. If the strings are small enough and no buffer expansion is triggered, then it will be faster than the call to AppendFormat because it won't have to parse the format string to figure out where to do the replacements.

More data is needed for a definitive answer

It should be noted that there is little discussion of using the static Concat method on the String class (Jon's answer using AppendWithCapacity reminded me of this). His test results show that to be the best case (assuming you don't have to take advantage of specific format specifier). String.Concat does the same thing in that it will predetermine the length of the strings to concatenate and preallocate the buffer (with slightly more overhead due to looping constructs through the parameters). It's performance is going to be comparable to Jon's AppendWithCapacity method.

Or, just the plain addition operator, since it compiles to a call to String.Concat anyways, with the caveat that all of the additions are in the same expression:

// One call to String.Concat. string result = a + b + c; 

NOT

// Two calls to String.Concat. string result = a + b; result = result + c; 

For all those putting up test code

You need to run your test cases in separate runs (or at the least, perform a GC between the measuring of separate test runs). The reason for this is that if you do say, 1,000,000 runs, creating a new StringBuilder in each iteration of the loop for one test, and then you run the next test that loops the same number of times, creating an additional 1,000,000 StringBuilder instances, the GC will more than likely step in during the second test and hinder its timing.

like image 189
casperOne Avatar answered Sep 29 '22 00:09

casperOne


casperOne is correct. Once you reach a certain threshold, the Append() method becomes slower than AppendFormat(). Here are the different lengths and elapsed ticks of 100,000 iterations of each method:

Length: 1

Append()       - 50900 AppendFormat() - 126826 

Length: 1000

Append()       - 1241938 AppendFormat() - 1337396 

Length: 10,000

Append()       - 12482051 AppendFormat() - 12740862 

Length: 20,000

Append()       - 61029875 AppendFormat() - 60483914 

When strings with a length near 20,000 are introduced, the AppendFormat() function will slightly outperform Append().

Why does this happen? See casperOne's answer.

Edit:

I reran each test individually under Release configuration and updated the results.

like image 37
John Rasch Avatar answered Sep 28 '22 22:09

John Rasch