StringBuilder在C#中的表现?

Emb*_*rja 5 c#

我有一个StringBuilder对象,我添加一些字符串,如下所示:

我想知道哪一个更好的方法,首先是这个:

StringBuilder sb = new StringBuilder();
sb.Append("Hello" + "How" + "are" + "you");
Run Code Online (Sandbox Code Playgroud)

第二个是:

StringBuilder sb = new StringBuilder();
sb.Append("Hello").Append("How").Append("are").Append("you");
Run Code Online (Sandbox Code Playgroud)

Ada*_*rth 10

在您当前的示例中,字符串文字:

"Hello" + "How" + "are" + "you"
Run Code Online (Sandbox Code Playgroud)

将由编译器编译成一个常量字符串文字,因此它在技术上比以下更快:

sb.Append("Hello").Append("How").Append("are").Append("you");
Run Code Online (Sandbox Code Playgroud)

但是,您是否使用字符串变量:

sb.Append(s1 + s2 + s3 + s4);
Run Code Online (Sandbox Code Playgroud)

然后后者会更快,因为前者可能会将最终字符串传递给Append方法之前创建一系列字符串(因为连接),而后者将避免额外的字符串创建(但交换额外的方法调用和内部缓冲区)调整).

更新:为了进一步清晰,在这种只有4个项目连接的确切情况下,编译器将发出一个调用String.Concat(string, string, string, string),知道字符串的长度和数量将比更高效StringBuilder.


Mar*_*ers 7

第一个会更有效率.编译器会将其转换为以下单个调用:

StringBuilder sb = new StringBuilder();
sb.Append("HelloHowareyou");
Run Code Online (Sandbox Code Playgroud)

衡量表现

知道哪个更快的最好方法是测量它.我会直言不讳:这是结果(较小的时间意味着更快):

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
Run Code Online (Sandbox Code Playgroud)

给出的数字是在紧密循环中执行操作1亿次的秒数.

结论

  • 最快的是使用字符串文字和+.
  • 但如果你有变量,使用Append速度比+.由于额外调用,第一个版本较慢String.Concat.

如果您想自己测试一下,这是我用来获得上述时间的程序:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)