【问题标题】:Use of Multiple String Builders for one string对一个字符串使用多个字符串生成器
【发布时间】:2011-10-15 15:01:42
【问题描述】:

所以我主要是 C# 和 Java 开发人员,但我想这个问题可能与任何使用 StringBuilder 或其衍生的编程语言有关。

好的,因此连接少量字符串可能成为主要的性能杀手,这或多或少是常识(尽管这值得商榷)。我的问题是是否有人知道在字符串生成器中使用字符串生成器的性能影响。为了澄清我的意思,让我包含一些应该有助于说明我的观点的虚拟代码。

我也意识到调用多个 StringBuilder 实例自然会影响性能,但我不相信我会调用它足以导致任何真正的性能问题。 (这个假设也可能是错误的,任何对此都有帮助的意见)

public string StringToGet()
{
     StringBuilder sb = new StringBuilder("Some Text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append(MethodThatCreatesAnotherString());
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append(MethodThatCreatesAnotherString());
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append(MethodThatCreatesAnotherString());
     //etc   

     return sb.toString();

}

private string MethodThatCreatesAnotherString()
{
     StringBuilder sb = new StringBuilder("Other text");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");
     sb.append("more text to add");

     return sb.ToString();
}

逻辑告诉我这不应该是一个问题,但这种方法的某些内容在我看来似乎不正确。任何人都可以对以下问题有所了解

  1. 与不使用其他方法和使用单个 StringBuilder 相比,这是否会产生显着更大的性能损失
  2. 是一种合理可接受的做法。

任何关于此的现场都将不胜感激。

【问题讨论】:

  • 这个问题应该得到更多的信任。这种算法肯定有应用。

标签: c# java string stringbuilder


【解决方案1】:

通常情况下,如果直连字符串的数量超过 5 个,最好使用StringBuilder。如果您可以控制反过来构建字符串的方法,为什么不考虑将您的 StringBuilder 传递给该方法?

public void MethodThatCreatesAnotherString(StringBuilder sb)
{
   // code that appends to StringBuilder
}

因此,当需要调用该函数时,传入当前的 StringBuilder,不会损失性能,但会以潜在的混淆为代价。

也就是说,除非您要参与成百上千个这样的操作,否则我不会担心这里的过早优化。您的主要性能损失是必须执行 两次 (即在方法内附加字符串,然后附加完整的字符串),但您仍然不会将性能损失达到使用的程度+ 串联。

编辑:如何使用它的说明性示例:

string SomeMethodCreatingAString()
{
   StringBuilder sb = new StringBuilder();
   sb.append("more text to add");
   sb.append("more text to add");
   sb.append("more text to add");
   sb.append("more text to add");
   sb.append("more text to add");
   MethodThatCreatesAnotherString(sb);
   // more text
   return sb.ToString();
}

因此,您永远不会在第二种方法中追加该字符串,您只需在该方法中使用相同的StringBuilder。希望这是有道理的。

【讨论】:

  • 这是一个非常好的观点 drharris 和 @Scott Munro 我很尴尬地说我没有考虑过。听起来在这种方法下,原始字符串构建器只是将 Append(SomeMethod()) 视为另一个基本上可以回答我的问题的字符串。
  • 我意识到我没有给出如何调用它的实际说明。希望您理解其意图,但万一其他人出现,我添加了一个示例。不用担心不考虑;这是一个设计决策,就像其他所有事情一样,它并不总是最好的方法。通过返回void,该方法隐藏了它的真正作用,这有时不是最好的方法。有时,您宁愿多花几毫秒的性能来获得更清晰的代码。
  • 我理解你的意图,但还是谢谢你。基于所有这些答案的一般意见,我认为,为了干净的代码,我最好避免在方法中返回“无效”,特别是考虑到性能影响可能非常小的事实。 .
【解决方案2】:

我不确定性能影响,但将MethodThatCreatesAnotherString 方法的签名更改为接受StringBuilder 将不再需要StringBuilder 的多个实例。

【讨论】:

    【解决方案3】:

    正如http://www.codinghorror.com/blog/2009/01/the-sad-tragedy-of-micro-optimization-theater.html 所示,连接字符串的不同方式之间的差异非常小,直到您获得真正大量的连接。

    因此,除非您已经知道这段代码存在性能问题,否则我认为这很好。在您的示例中,您实际上只获得了 3 个额外的字符串构建器初始化和 3 个额外的字符串分配。

    从长远来看,您应该尝试做最简单的事情,并且只在确定需要它们并且测试将它们暴露出来时才担心复杂的微优化。

    【讨论】:

    • +1 这当然是一个公平的观点,但是因为我确实倾向于本能地使用 StringBuilder 可以这么说,我的问题实际上旨在确保使用所谓的“嵌入式”没有绝对错误' 字符串生成器。感谢您分享这篇文章。
    猜你喜欢
    • 1970-01-01
    • 2012-02-02
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多