StringBuilder是否比连接十几个字符串慢? 编译器如何优化字符串连接,以便使用“+”连接十几个字符串将比StringBuilder更好?
从一本书(由Ben Watson编写)中说:
String Concatenation:用于已知的简单连接(在编译时) 时间)字符串的数量,只需使用'+'运算符或 String.Concat方法。这通常比使用a更有效 StringBuilder的。 string result = a + b + c + d + e + f;不要 考虑StringBuilder,直到字符串的数量是可变的 可能比几打还要大。编译器将优化简单 字符串连接以减少内存开销。
答案 0 :(得分:8)
String.Concat
更有效率,因为它从一开始就知道所有字符串长度。因此,它可以分配一个具有恰当长度的缓冲区,将字符串复制到其中并返回该缓冲区。
StringBuilder
必须分配一个小缓冲区,每次调用Append
时都会重新分配和复制,导致空间不足。对ToString()
的最后调用还必须分配另一个缓冲区。
所以当你事先知道你有多少个字符串时,请使用String.Concat
;当你没有时,请使用StringBuilder
。
在C#中,对+运算符的链式调用会自动转换为对String.Concat
的单个调用。
答案 1 :(得分:1)
直接连接需要较少的对象和内存调用。所以如果你在一个语句中连接所有字符串(没有任何文本处理),它会更快。
在这种情况下,编译器可以计算新字符串的大小并分配内存并将所有字符复制到其中。所以你只创建你想要的对象。
如果您使用的是StringBuilder,则使用其他对象。如果附加长字符串而不告诉构造函数中的StringBuilder使用巨大的缓冲区大小,则字符串构建器可能会执行多个内存分配和副本,因为它可能会在标准内存分配上运行多次。
如果在循环中构建字符串,StringBuild是更好的解决方案。在这种情况下,直接连接将在每次迭代中创建一个新对象和内存分配,其中StringBuild仅使用一个内存分配(如果在构造函数中使用正确的值)并且只使用两个对象。
但是很难说出运行时的内容。实施随时间而变化。那么现在最好的做法可能是5年内最糟糕的做法。