最近我发现自己使用StringBuilder进行所有字符串连接,无论大小,但是在最近的性能测试中,我换掉了同事的stringOut = string1 +"." String2样式连接(在一个10000x +循环中使用,每次都是StringBuilder)用于StringBuilder只是为了看看它在次要连接中会有什么不同.
我发现,在性能测试的许多次运行中,无论是串联还是StringBuilder,更改都无论是更高还是更低(重申这是针对小型连接).
在什么时候,StringBuilder对象的"newing up"否定了使用它的好处?
我遵循的规则是 -
在编译时未知连接数时使用StringBuilder.
因此,在您的情况下,每个StringBuilder只会附加几次然后被丢弃.这与事情并不完全相同
string s = String.Empty; for (int i = 0; i < 10000; ++i) { s += "A"; }
使用StringBuilder会大大提高性能,因为否则会不断分配新的内存.
我确定我有另一个答案,我发布了一篇链接到我的文章,然后是它的摘要,但是我们再来一次.
StringBuilder
当你在一个非平凡的循环中连接时肯定会使用- 特别是如果你不确定(在编译时)你将通过循环进行多少次迭代.例如,一次读取一个文件,使用+ =运算符构建一个字符串可能会导致性能自杀.
当你可以(可读地)指定需要在一个语句中连接的所有内容时,绝对使用连接运算符.(如果要连接的数组,请考虑String.Concat
显式调用- 或者String.Join
如果需要分隔符.)
不要害怕将文字分成几个连接位 - 结果将是相同的.例如,您可以通过将长文字分成几行来提高可读性,而不会损害性能.
如果您需要连接的中间结果而不是提供下一次连接迭代,StringBuilder
则不会对您有所帮助.例如,如果您从名字和姓氏建立一个全名,然后在最后添加第三条信息(可能是昵称),那么只有StringBuilder
在您不需要时才能从中受益用于其他目的的(名字+姓氏)字符串(正如我们在创建Person
对象的示例中所做的那样).
如果你只是有几个串连的事,和你真正想要做他们单独的语句,它并没有真正不管你走哪条路.哪种方法更有效,将取决于级联串的大小参与的数量,和他们连接在一起的顺序.如果你真的相信这段代码是一个性能瓶颈,配置文件或基准两者兼得.
有时值得查看文档:
String或StringBuilder对象的串联操作的性能取决于内存分配发生的频率.字符串连接操作始终分配内存,而StringBuilder连接操作仅在StringBuilder对象缓冲区太小而无法容纳新数据时分配内存.因此,如果连接固定数量的String对象,则String类更适合并置操作.在这种情况下,编译器甚至可以将单个连接操作组合成单个操作.如果连接任意数量的字符串,则StringBuilder对象最好用于连接操作; 例如,如果循环连接随机数量的用户输入字符串.
在您的示例中,每个输出字符串只有一个连接,因此StringBuilder不会获得任何结果.在多次添加相同字符串的情况下,您应该使用StringBuilder ,例如:
stringOut = ... for(...) stringOut += "." stringOut += string2