是否需要使用stringbuilder?

Col*_*ech 6 c# string clr stringbuilder cil

我们都知道连接字符串会导致效率问题,特别是在循环中.我被教导用来StringBuilder防止这些问题.

所以这:

str += someotherstring
Run Code Online (Sandbox Code Playgroud)

变成这样:

StringBuilder sb = new StringBuilder();   
sb.AppendLine(someotherstring);
Run Code Online (Sandbox Code Playgroud)

但我的理解是.NET框架3.5及更高版本中的CLR足够智能,可以为这两种方法输出相同的IL.那么我是否应该在我的团队代码评论中强制执行stringbuilder?

编辑:我认为Servy在评论中点头:

在连接编译时已知的许多字符串时就是这种情况.因此,当在编译时连接多个字符串时,不需要使用SB.当在编译时连接许多未知的字符串时,它不能这样做

Rah*_*thi 7

不,这并不总是正确的.我不知道如果你检查这个如何提高Visual C#中的字符串连接性能#

但是,.NET Framework包含一个针对字符串连接进行了优化的StringBuilder类.它提供了与在C/C++中使用字符数组相同的好处,以及自动增加缓冲区大小(如果需要)并为您跟踪长度.本文中的示例应用程序演示了StringBuilder类的用法,并将性能与串联进行了比较.

当您在代码传递中执行多个循环或分叉时,StringBuilder更可取.

还检查一下

StringBuilder并不总是更快 - 第1部分,共2部分

这段代码在我的电脑上运行了1484毫秒:

for (int i = 0; i <= 1000000; i++)  { 
    // Concat strings 3 times using StringBuilder 
    StringBuilder s = new StringBuilder(); 
    s.Append(i.ToString()); 
    s.Append(i.ToString()); 
    s.Append(i.ToString());  }
Run Code Online (Sandbox Code Playgroud)

而这一个,使用传统的连接,花费的时间略少(1344毫秒):

for (int i = 0; i <= 1000000; i++)  { 
    // Concat strings 3 times using traditional concatenation 
    string s = i.ToString(); 
    s = s + i.ToString(); 
    s = s + i.ToString();  }
Run Code Online (Sandbox Code Playgroud)

以上数据表明,一旦连接数超过3,StringBuilder才会开始更快地工作.

蒂姆发表的评论中有很好的联系

经验法则

那么,什么时候应该使用StringBuilder,何时应该使用字符串连接运算符?

  • 当您在一个非平凡的循环中连接时,肯定会使用StringBuilder - 特别是如果您不确定(在编译时)您将通过循环进行多少次迭代.例如,一次读取一个文件,使用+ =运算符构建一个字符串可能会导致性能自杀.
  • 当你可以(可读地)指定需要在一个语句中连接的所有内容时,绝对使用连接运算符.(如果要连接的数组,请考虑显式调用String.Concat - 如果需要分隔符,请考虑String.Join.)
  • 不要害怕将文字分成几个连接位 - 结果将是相同的.例如,您可以通过将长文字分成几行来提高可读性,而不会损害性能.
  • 如果您需要连接的中间结果,而不是提供下一次连接迭代,StringBuilder不会帮助您.例如,如果你从名字和姓氏建立一个全名,然后在最后添加第三条信息(昵称,也许),你只会受益于使用StringBuilder,如果你不这样做需要(名字+姓氏)字符串用于其他目的(正如我们在创建Person对象的示例中所做的那样).
  • 如果你只需要进行一些连接,并且你真的想在单独的语句中进行这些连接,那么你走哪条路并不重要.哪种方式更有效将取决于所涉及的字符串大小的串联数量,以及它们连接的顺序.如果您确实认为这段代码是性能瓶颈,则可以通过两种方式对其进行分析或基准测试.

  • 所以说当连接超过3个字符串时你应该使用SB是不正确和误导的.要连接的字符串数量不是唯一要考虑的因素,它只是其中之一. (2认同)

Hab*_*bib 2

但据我了解,.NET Framework 3.5 及更高版本中的 CLR 足够智能,可以为两种方法输出相同的 IL。

不,那没有必要。您不能依赖编译器在循环中对此进行优化。它也更好用StringBuilder,因为它在字符串连接方面肯定会更好,并且提供更好的可读性。

  • 尽管我同意你的大部分答案,但“更好的可读性”是首选。我更喜欢标准串联的可读性。 (2认同)