string连接vsstring生成器。 性能

我有一个情况,我需要连接几个string形成一个类的ID。 基本上我只是在列表中循环获取对象的ToString值,然后连接它们。

foreach (MyObject o in myList) result += o.ToString(); 

这份名单预计不会超过5个元素(虽然它可能只是一个非常非常小的情况),通常会有1到3个元素,通常只有一个或两个元素。

什么是更好的性能,保持串联或使用StringBuilder?

 StringBuilder bld = new StringBuilder() foreach (MyObject o in myList) bld.Append(o.ToString()); 

我不确定在最常见的情况下,创buildStringBuilder比标准连接需要更多的时间。

这是懒惰的,列表中的项目一旦创build就不会改变,所以当被调用的时候,id是懒惰地构造的。

作为一个侧面说明…我应该使用固定的数组,而不是一个列表? 如果我这样做,我会得到任何performance或记忆改善吗? (无论如何,List只能用作IEnumerable)

对这个问题更普遍的看法可能是,有多less个string足以停止连接并开始构build?

我应该甚至打扰testing案例的情况?

 if (myList.Count > 4) ConcatWithStringBuilder(myList); 

通常的答案是string连接对于4到8个string更有效。 这取决于你阅读的是谁的博客。

不要写testing来决定使用哪种方法。 如果你不确定是否会超越魔法限制,那么就使用StringBuilder。

运行此代码以查看自己的结果:

 const int sLen=30, Loops=5000; DateTime sTime, eTime; int i; string sSource = new String('X', sLen); string sDest = ""; // // Time string concatenation. // sTime = DateTime.Now; for(i=0;i<Loops;i++) sDest += sSource; eTime = DateTime.Now; Console.WriteLine("Concatenation took " + (eTime - sTime).TotalSeconds + " seconds."); // // Time StringBuilder. // sTime = DateTime.Now; System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1)); for(i=0;i<Loops;i++) sb.Append(sSource); sDest = sb.ToString(); eTime = DateTime.Now; Console.WriteLine("String Builder took " + (eTime - sTime).TotalSeconds + " seconds."); // // Make the console window stay open // so that you can see the results when running from the IDE. // Console.WriteLine(); Console.Write("Press Enter to finish ... "); Console.Read(); 

参考。 http://support.microsoft.com/kb/306822

我支持保持简单的想法,直到你有一个很好的理由使它们变得复杂。

对于像2-5个元素的东西,使用StringBuilder没有意义(除非你连续重复这个连接)。 更好的可读语法“+ =”具有更多的价值。

对这个问题更普遍的看法可能是,有多less个string足以停止连接并开始构build?

这取决于string的长度,如果你可以预测目标长度, 那么你应该提供给StringBuilder构造函数的长度 ,如果你一次或几步连接它们。

如果你一次连接它们(比如s = "A" + "b" + "c" + "d" ),那么使用StringBuilder可能永远没有意义。

如果你能够准确的预测长度,那么即使是3stringStringBuilder也会更快。

如果你有5个以上的连接,通常StringBuilder会更快。 但即使如此,串联string通常也没有多less开销(除非运行在一个紧密的循环中)。

只要你达到10个连接使用StringBuilder可能是有利的。

编辑:只是要清楚:在你的情况下,你应该清楚地去没有StringBuilder

IMOstring连接更具可读性。 你可以使用+和+ =而不是strBldInstance.Add(),它可以使代码更加浑浊,

StringBuilder的存在使得连接更加高效,但是我通常牺牲了代码可读性的性能。 你的代码不会受到影响,如果你在这里和那里几个string。 对于经常使用多个string的代码块,请使用StringBuilder。

为什么你不能使用

 String.Concat(myList) 

而不是重新发明轮子? 它具有很高的性能,但是却很简单。
更多信息在这里: http : //msdn.microsoft.com/en-us/library/system.string.concat.aspx

如果你可以估算完整string的字节数(并用它来初始化StringBuilder的容量),那么StringBuilder在执行超过大约3个连接时可能会超越String类。

在这种情况下,string生成器很可能会稍微快一些,但实际上可能还不够。 这实际上取决于两件事情,你重新创buildstring的次数(因为string是不可变的,并且连接一个新的string以从两个现有的string创build),以及string元素的大小串联在一起。 连接5个string,每个字节为2个字节,与将5个string连接在一起,每个字节为5000个字节将会非常不同,因为string越长,系统为分配内存和垃圾收集对象所做的工作就越多使用时间更长。 string生成器是一个更好的select,因为它已经被优化,可以将string连接在一起,而且您不必担心性能方面的考虑。

考虑到这一切,如果你知道最终string的最终大小有多大,string生成器几乎肯定会更快。 当你告诉它为最终的string分配多less内存时,不需要经过重新分配内存的过程。

我会使用StringBuilder只是因为你想在整个应用程序中保持一致。 实例化一个Java / .NET对象也不费时,但我猜测在设置StringBuilder时会有一些内务pipe理。 没有比通过串联创build多个String对象更糟糕了。

如果可以的话,你可以有一些乐趣,完全消除for循环,并使用聚合?

 var concatstring = mylist.Aggregate("", (acc, item) => acc + "." + item); 

不知道在这个虽然开销?