2010-11-16 60 views

回答

15

简答题:StringBuilder适用于连接任意数量的字符串的情况,这些字符串在编译时并不知道。

如果知道你在编译的时候结合了哪些字符串,StringBuilder基本上是没有意义的,你不需要它的动态调整能力。

示例1:您想结合“猫”,“狗”和“鼠标”。这正好是11个字符。你可以简单地分配长度为11的char[]数组,并用来自这些字符串的字符填充它。这实质上是string.Concat所做的。

示例2:您想要将未指定数量的用户提供的字符串合并为一个字符串。由于要提前并置的数据量未知,因此在这种情况下使用StringBuilder即可。

16

StringBuilder的是不是一定会更快。我记得,如果你连接少于十几个字符串,字符串concatentation(其他的通过String.Concat或简单的str1 + str2)实际上更快。原因是StringBuilder的分配和初始化实际上需要时间。

StringBuilder更快的原因是它创建了一个内部缓冲区,它添加了字符串。如果连接了20个字符串,StringBuilder只是将一个接一个地附加到缓冲区,最后在请求时通过其ToString()方法返回结果。 (我假设有足够的缓冲区空间,否则StringBuilder会担心重新分配缓冲区,并且有帮助它不要重新分配太多时间的启发法。)如果你是字符串联合,每个字符串concat会分配一个新的字符串长度(str1.Length + str2.Length)并将第一个和第二个字符串复制到位。这导致了很多字符串的重新复制。

var result = str1 + str2 + str3 + ... + strN; 

这将需要N-1个分配和N-1个复制操作。这对于大N来说可能非常昂贵。另外请注意,您正在复制str1的内容N-1次。一次得到str1 + str2的结果。然后再次得到(str1 + str2)+ str3的结果。使用StringBuilder,每个字符串只会复制到内部缓冲区一次,假设缓冲区足够大以容纳单个字符串。

+5

我相信你的结尾段落的前几句话是不正确的。以这种方式连接许多字符串的单行将会,除非我错误,编译为一个'string.Concat'调用,它为结果字符串分配足够的空间一次,而不需要按照您的建议执行多次重新分配。 – 2010-11-16 04:11:07

+0

C#编译器可能会有这种优化。我没有检查过。通常情况下,这些类型的连接是在for循环中完成的,不能被优化。 C#编译器针对您将一系列常量字符串进行连接的情况进行优化,这会导致编译器发出单个常量字符串并完全避免运行时连接。 – 2010-11-16 04:16:10

相关问题