何时使用StringBuilder?

19

可能是重复问题:
String vs StringBuilder

我刚刚翻阅了一些VB.NET的书籍,但不确定StringBuilder是什么,也不确定如何使用它。

在使用时有哪些指导原则?当你连接两个字符串或者50个字符串时,最好使用它吗?

还是当总字符串长度大于128个字符时?

或者,每当你使用它来添加字符串时,你都会看到性能提升吗?

在哪种情况下,使用StringBuilder实例构建SQL语句比使用string.format("Select * from x where y = {0}",1)更好?

对于小字符串拼接,声明另一个变量并包含名称空间并没有什么益处,但现在我也不确定了。

抱歉,很多文档告诉你要使用什么,但没有告诉你什么最好。


尝试这个问题: https://dev59.com/RHVD5IYBdhLWcg3wI4CM - BC.
6个回答

40

我有一篇关于这个主题的文章。 总结如下(摘自页面底部):

  • 在非平凡循环中连接字符串时,一定要使用StringBuilder——尤其是如果您不确定(在编译时)将通过循环进行多少次迭代。例如,逐字符读取文件,使用+=操作符随着进度创建一个字符串可能导致性能问题。
  • 当你可以(可读性良好地)指定需要连接的所有内容时,一定要使用连接运算符。(如果您有一个需要连接的东西数组,请考虑显式调用String.Concat - 或者如果需要分隔符,请使用String.Join。)
  • 不要害怕将文字量拆分成几个连接的位——结果将是相同的。您可以通过将长文字拆分为几行来帮助阅读,例如,对性能没有伤害。
  • 如果您需要连接的中间结果与提供给连接的下一次迭代以外的目的不同,StringBuilder将无法帮助您。例如,如果您从名字和姓氏构建一个全名,然后添加第三个信息(也许是昵称)到末尾,只有在您不需要(名字+姓氏)字符串用于其他目的时才会从使用StringBuilder中受益(例如,我们在创建Person对象的示例中使用的方法)。
  • 如果您只有几个连接要完成,并且您确实希望将它们分开执行,那么无论哪种方式都不会真正影响。哪种方式更有效率取决于连接的数量、涉及字符串的大小以及它们被连接的顺序。如果您真的认为这段代码是性能瓶颈,请对其进行分析或基准测试。

1
你好,你有没有对比过 StringBuilder 和 String.Concat(theStrings.ToArray()) 的性能呢?实际上,String.Concat 是一种相当高效的方法。 - JaredPar
如果您已经在一个数组中拥有了所有需要的字符串,那么我期望 String.Concat 应该非常快 - 它可以完美地计算出所需的起始大小。不过,不得不首先将列表转换为数组是不幸的。一个 String.Concat(IList<string>) 会很好。 - Jon Skeet
哦,另外的消息是:剪切和粘贴赢了;) - Jon Skeet

14

这是我的经验法则:

StringBuilder最好在编译时无法确定连接数量的情况下使用。


好的,这意味着99%的数据库应用程序不会使用stringbuilder来构建SQL语句,但有时您不确定要连接多少个“where”到结尾,总是1...但不应超过3,您是否仍然会使用stringbuilder? - spacemonkeys
这是一个很好的经验法则,但偶尔如果你正在构建一个非常大的字符串,但不使用循环,那么使用 StringBuilder 会更好。 - BC.
@BC - 很好的观点 - 经验法则总有例外 :) - Andrew Hare

3

0
个人而言,当我有超过一两个字符串需要连接时,我会使用 StringBuilder。我不确定是否存在真正的性能损失,但我总是读到并被告知每次使用常规连接多个字符串时都会创建一个额外的字符串副本, 而使用 StringBuilder 则保留一个副本,直到您在其中调用最终ToString()方法。

0

有人通过实验发现,关键数字是6。如果连续超过6个连接,则应使用StringBuilder。我不记得在哪里找到这个信息了。

但是,请注意,如果您只是在一行中编写此内容:

"qwert" + "yuiop" + "asdf" + "gh" + "jkl;" + "zxcv" + "bnm" + ",."

这将被转换为一个函数调用(我不知道如何在VB.net中编写它)

String.Concat("qwert", "yuiop", "asdf", "gh", "jkl;", "zxcv", "bnm", ",.");

如果你在一行上执行所有的串联操作,那么不必使用 StringBuilder,因为 String.Concat 实际上会在一次操作中完成所有的串联。只有在循环或连续串联时才需要使用 StringBuilder。


0
我的规则是,在 For 或 Foreach 循环中添加字符串时,请使用 StringBuilder。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接