6

我正在阅读一本名为 .NET Gotchas 的书(非常值得一读 IMO),它说明了 String 和 StringBuilder 之间的性能差异,它提出了一个我觉得无法回答的问题!虽然我不知道这两个类的内部结构(没有查看这些类的反射版本),但我想知道;既然 .NET 中的运算符是可重载的,为什么微软没有实现 String 类在内部使用 StringBuilder 并重载串联运算符以简单地调用 StringBuilder 中的 .Append()?我猜有一些根本原因说明为什么不是这样,如果是这样,为什么?

4

2 回答 2

7

问题不在于字符串连接很慢,而更多的是重复连接会产生大量需要分配的中间字符串,然后再进行垃圾收集。

编辑
注意,mystring += "a"不要简单地将“a”添加到前一个字符串。它为组合创建一个新字符串并将“mystring”指向它,从而丢弃以前的值(如果没有更多对它的引用)。

结束编辑

一系列的

string mystring = "something";
mystring += "something else";
mystring = mystring + "third";

如果您将每个单独的行作为 StringBuilder Append 执行,然后执行 .ToString() 以将结果返回到字符串中,则会执行较慢。如果您重复使用单个 StringBuilder、Append() 并在最后执行 .ToString(),您只会获得性能优势。

StringBuilder sb = new StringBuilder();
sb.Append("something");
sb.Append("something else");
sb.Append("third");
string mystring = sb.ToString();

然后一个 StringBuilder 有它自己的开销,所以如果你有少量的字符串部分要加入,它不会使你受益。

请注意,编译器在单个语句中优化了串联:

string mystring = "something" + "something else" + "third";

最快。

于 2012-08-02T10:15:34.280 回答
5

原因很简单:

因为

string result = a + b;

var sb = new StringBuilder(a, a.Length + b.Length);
sb.Append(b);
string result = sb.ToString();

StringBuilders 仅在发生大量连接时才有意义,通常在循环内。

于 2012-08-02T10:08:00.763 回答