我知道在C#中使用StringBuilder的明显性能优势,但它的内存差异如何?
StringBuilder是否使用更多的内存?作为一个附注,stringbuilder到底有什么不同的地方使它更快?
简短回答: 当你需要连接一个数量未知的字符串并且在编译时无法确定这些字符串时,StringBuilder
是适当的选择。
如果你在编译时知道要连接哪些字符串,那么使用 StringBuilder
就没有必要了,因为你不需要它的动态调整大小的能力。
例如 1: 如果你想要连接 "cat", "dog" 和 "mouse" 这三个字符串,它们总共有11个字符。你可以简单地分配一个长度为11的 char[]
数组,并将这些字符串的字符填充到数组中。这基本上就是 string.Concat
所做的事情。
例如 2: 如果你想将未指定数量的用户提供的字符串连接成一个单一的字符串。由于要连接的数据量预先未知,因此在这种情况下使用 StringBuilder
是适当的。
StringBuilder并不一定更快。据我所知,如果你连接的字符串少于十个,字符串连接(无论是通过String.Concat还是简单的str1 + str2)实际上更快。原因是分配和初始化StringBuilder实际上需要时间。
StringBuilder更快的原因是它创建了一个内部缓冲区,将字符串添加到其中。如果您连接20个字符串,StringBuilder只需将一个接一个地附加到其缓冲区,最后在请求时返回结果-通过它的ToString()方法。 (我假设有足够的缓冲区空间。否则,StringBuilder会担心重新分配缓冲区,并具有帮助它不过多重新分配的启发式算法。)如果你连接的是字符串,每个字符串连接都会为长度为(str1.Length + str2.Length)的新字符串分配内存,并将第一个和第二个字符串复制到指定位置。这导致了大量的字符串重新复制。
var result = str1 + str2 + str3 + ... + strN;
这将需要N-1次分配和N-1次复制操作,对于大的N来说这可能会非常昂贵。请注意,您正在复制str1的内容N-1次。一次是为了得到str1+str2的结果。然后再次得到(str1+str2)+str3的结果。使用StringBuilder,只需要将每个字符串拷贝到内部缓冲区一次,假设缓冲区足够大以容纳各个字符串。
string.Concat
调用,它只需一次性分配足够结果字符串所需的空间,而不需要像你所暗示的那样进行多次重新分配。 - Dan Tao