在什么时候不使用StringBuilder变得微不足道的或者开销?
-
23-08-2019 - |
题
最近,我发现自己使用StringBuilder所有串串联,不论大小,但是在最近的一次性能测试我换了一位同事的 stringOut=string1+"."string2 风格拼接(被用于10000x+循环StringBuilder被newed每次)为StringBuilder只是为了看看有什么区别,它将使在一小串联。
我发现,在许多运行的性能测试,改变既不明显较高或较低的无关联或StringBuilder(重申这是为了 小 串联).
在什么时候不会'newing了'的StringBuilder目否定的好处,使用一个吗?
解决方案
这我遵循的规则是 -
使用一个StringBuilder当级联的数目在编译时未知的。
因此,在你情况下,每个的StringBuilder只追加一个几次,然后被丢弃。这是不是真的一样像
string s = String.Empty;
for (int i = 0; i < 10000; ++i)
{
s += "A";
}
使用一个StringBuilder将大大提高性能,因为否则你将被不断分配新的内存中。
其他提示
我确信我还有另一个答案在哪里我只是一个 链接到我的文章 然后其摘要,但这里我们再去。
肯定使用
StringBuilder
当你串联在一个不平凡的循环,尤其是如果你肯定不知道(在编制时间)有多少你迭代将使经过循环。例如,阅读一个文件的一个角色的时间,建立一串为你去使用+=操作者的潜在表现自杀。肯定是使用联运营商的时候你可以(可读性)指定一切的需要是连接在一个发言。(如果你有一系列的事情连接,考虑叫
String.Concat
明确或String.Join
如果你需要一个界定符。)不要害怕打破文字的成几个串连的位的结果将会是相同的。你可以帮助读通过打破长为几行文字,例如,没有伤害性。
如果你需要的中间结果并置于比其他的东西喂养下一代的连接,
StringBuilder
并不能帮助你。例如,如果建立起一个全名从第一名和一个最后的名称,然后添加一个第三条信息(绰号,也许)到最后,你将只会从中受益的使用StringBuilder
如果你不需要(第一名+最后一个名称)串用于其他目的(如我们在例如它创建了一个Person
对象)。如果你只有几串联的事,你真的想这样做,他们在单独发言,它并不真正论你走哪条路.哪个方向是更高效将取决于数目的串联的大小串的参与,并什么了他们在连接。如果你真的相信那个代码是一个业绩的瓶颈,配置文件或基准,这两个方式。
有时,这是值得期待的文档:
级联的性能 用于字符串的操作或 StringBuilder对象取决于如何 常发生的存储器分配。一种 字符串连接操作总是 分配存储器,而 StringBuilder的级联操作 只有分配内存,如果 StringBuilder对象缓冲区太小 小,以适应新的数据。 因此,String类是 优选用于级联 操作如果字符串的固定数量 对象是连接在一起。在那里面 情况下,个别级联 操作甚至可以合并成 由编译器的单个操作。一种 StringBuilder对象是优选 如果一个置运算 字符串的任意数 级联;例如,如果一个循环 串接的随机数 用户输入的字符串。
在你的榜样,只有每个输出字符串中的一个串联,所以StringBuilder的获得你什么。你应该在你添加到的相同的字符串的很多次的情况下,e.g使用StringBuilder:
stringOut = ...
for(...)
stringOut += "."
stringOut += string2
我的原则是简单的。
- 如果你有理由可以写一个单一的表达产生的最终,那么使用
+
. - 如果你不能(由于尺寸或变异性),然后使用StringBuilder.
以我的经验、表达方式,如:
"Id: " + item.id + " name: " + item.name
可以编写和理解更易于:
StringBuilder sb = new StringBuilder();
sb.append("Id: ").append(item.id);
sb.append(" name: ").append(item.name);
(随后由使用的字符串 sb
在表达上述会已经编写的),并且执行同样(暗示:看看编码来看看为什么!)
另一方面,当有必要积累了一串随时间(如运行的程序)或空间(由的价值观来自不同部分的代码),在一个方式是不切实际的编写作为一个单一的线路的表达,然后StringBuilder避免了的开销(时间和存储-翻腾):
String s = somethingExpression;
...
s += someOtherExpression;
...
s += yetAnotherExpression;
...
从 MSDN :
[T]他String类优选的是一个 如果固定的级联操作 String对象的数目是 级联。在这种情况下, 个别级联操作 甚至可以合并成一个单一 由编译器操作。一种 StringBuilder对象是优选 如果一个置运算 字符串的任意数 级联;例如,如果一个循环 串接的随机数 用户输入的字符串。
我想答案是“这取决于” - 如果你在循环中串联有超过少数的迭代,然后一个StringBuilder几乎总是提供更好的性能,但肯定知道的唯一途径是真正的个人资料
有在编码恐怖在此过一个有趣的文章。杰夫得到了100000次迭代的结果如下在双核3.5 GHz的酷睿2:
Simple Concatenation - 606 ms
String.Format - 665 ms
string.Concat - 587 ms
String.Replace - 979 ms
StringBuilder - 588 ms
从点网皮尔斯的:
当于使用StringBuilder?
的StringBuilder完全是一种优化,并提供没有逻辑改进使用concat比其内部实现其他。这就是说,关键是要在高性能的应用程序和网站正确地使用它。
有时候,它是好的使用的4个或更少的迭代小环与简单的字符串Concats。然而,在边缘情况下,这可能是灾难性的。计划你的优势例StringBuilder的。