Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StringBuilder performance in C#?

Tags:

c#

I have a StringBuilder object where I am adding some strings like follows:

I want to know which one is better approach here, first one is this:

StringBuilder sb = new StringBuilder();
sb.Append("Hello" + "How" + "are" + "you");

and the second one is:

StringBuilder sb = new StringBuilder();
sb.Append("Hello").Append("How").Append("are").Append("you");
like image 810
Embedd_0913 Avatar asked Aug 13 '12 16:08

Embedd_0913


3 Answers

The first will be more efficient. The compiler will convert it to the following single call:

StringBuilder sb = new StringBuilder();
sb.Append("HelloHowareyou");

Measuring the performance

The best way to know which is faster is to measure it. I'll get straight to the point: here are the results (smaller times means faster):

sb.Append("Hello" + "How" + "are" + "you")                  : 11.428s
sb.Append("Hello").Append("How").Append("are").Append("you"): 15.314s
sb.Append(a + b + c + d)                                    : 21.970s
sb.Append(a).Append(b).Append(c).Append(d)                  : 15.529s

The number given is the number of seconds to perform the operation 100 million times in a tight loop.

Conclusions

  • The fastest is using string literals and +.
  • But if you have variables, using Append is faster than +. The first version is slower because of an extra call to String.Concat.

In case you want to test this yourself, here's the program I used to get the above timings:

using System;
using System.Text;

public class Program
{
    public static void Main()
    {
        DateTime start, end;
        int numberOfIterations = 100000000;
        start = DateTime.UtcNow;
        for (int i = 0; i < numberOfIterations; ++i)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Hello" + "How" + "are" + "you");
        }
        end = DateTime.UtcNow;
        DisplayResult("sb.Append(\"Hello\" + \"How\" + \"are\" + \"you\")", start, end);

        start = DateTime.UtcNow;
        for (int i = 0; i < numberOfIterations; ++i)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Hello").Append("How").Append("are").Append("you");
        }
        end = DateTime.UtcNow;
        DisplayResult("sb.Append(\"Hello\").Append(\"How\").Append(\"are\").Append(\"you\")", start, end);

        string a = "Hello";
        string b = "How";
        string c = "are";
        string d = "you";

        start = DateTime.UtcNow;
        for (int i = 0; i < numberOfIterations; ++i)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(a + b + c + d);
        }
        end = DateTime.UtcNow;
        DisplayResult("sb.Append(a + b + c + d)", start, end);

        start = DateTime.UtcNow;
        for (int i = 0; i < numberOfIterations; ++i)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(a).Append(b).Append(c).Append(d);
        }
        end = DateTime.UtcNow;
        DisplayResult("sb.Append(a).Append(b).Append(c).Append(d)", start, end);

        Console.ReadLine();
    }

    private static void DisplayResult(string name, DateTime start, DateTime end)
    {
        Console.WriteLine("{0,-60}: {1,6:0.000}s", name, (end - start).TotalSeconds);
    }
}
like image 32
Mark Byers Avatar answered Nov 15 '22 18:11

Mark Byers


In your current example, the string literals:

"Hello" + "How" + "are" + "you"

Will be compiled into one constant string literal by the compiler, so it is technically faster than:

sb.Append("Hello").Append("How").Append("are").Append("you");

However, were you to use string variables:

sb.Append(s1 + s2 + s3 + s4);

Then the latter would be faster as the former could potentially create a series of strings (because of the concatenation) before passing the final string into the Append method, whereas the latter would avoid the extra string creations (but trades off extra method calls and internal buffer resizing).

Update: For further clarity, in this exact situation where there are only 4 items being concatenated, the compiler will emit a call to String.Concat(string, string, string, string), which knowing the length and number of strings will be more efficient than StringBuilder.

like image 83
Adam Houldsworth Avatar answered Nov 15 '22 19:11

Adam Houldsworth


String constants will be concatenated at compile time by the compiler. If you are concatenating no more than four string expressions, the compiler will emit a call to String.Concat

s + t + u + v ==> String.Concat(s, t, u, v)

This performs faster than StringBuilder, as StringBuilder might have to resize its internal buffer, while Concat can calculate the total resulting length in advance. If you know the maximum length of the resulting string in advance, however, you can initialize the StringBuilder by specifying an initial working buffer size

var sb = new StringBuilder(initialBufferSize);

StringBuilder is often used in a loop and other dynamic scenarios and performs faster than s += t in such cases.

like image 4
Olivier Jacot-Descombes Avatar answered Nov 15 '22 19:11

Olivier Jacot-Descombes