StringBuilder 真的比连接一打字符串慢吗?

Is it true that StringBuilder is slower than concatenate a dozen of strings?

StringBuilder 真的比连接一打字符串慢吗? 编译器如何优化字符串连接,以便使用“+”连接十几个字符串会比 StringBuilder 更好?

从一本书(由 Ben Watson 撰写)中说:

String Concatenation: For simple concatenation of a known (at compile time) quantity of strings, just use the ‘+’ operator or the String.Concat method. This is usually more efficient than using a StringBuilder. string result = a + b + c + d + e + f; Do not consider StringBuilder until the number of strings is variable and likely larger than a few dozen. The compiler will optimize simple string concatenation in a way to lessen the memory overhead.

String.Concat 更有效,因为它从一开始就知道所有的字符串长度。因此它可以分配一个长度恰到好处的缓冲区,将字符串复制到其中,然后 return 该缓冲区。

StringBuilder 必须分配一个小缓冲区,每次调用 Append 导致它从 space 中变为 运行 时重新分配和复制。对 ToString() 的最终调用还必须分配另一个缓冲区。

所以当你事先知道你有多少个字符串时使用String.Concat;不使用时使用 StringBuilder

在 C# 中,对 + 运算符的链式调用会自动转换为对 String.Concat.

的单个调用

直接连接需要更少的对象和内存调用。因此,如果您在一个语句中连接所有字符串(不进行任何文本处理),速度会更快。

在这种情况下,编译器可以计算新字符串的大小并分配内存并将所有字符复制到其中。所以你只创建你想要的对象。

如果您使用的是 StringBuilder,则需要使用一个额外的对象。如果您附加长字符串而不告诉构造函数中的 StringBuilder 使用巨大的缓冲区大小,则字符串生成器可能会进行多次内存分配和复制,因为它可能 运行 超过标准内存分配数次。

如果您在循环中构建字符串,StringBuild 是更好的解决方案。在这种情况下,直接连接将在每次​​迭代中创建一个新对象和内存分配,其中 StringBuild 仅使用一个内存分配(如果您在构造函数中使用正确的值)并且仅使用两个对象。

但很难说出关于 运行 时间的事情。实施会随着时间而改变。所以现在最好的做法可能是 5 年后最差的做法。