stringbuilder与string concat

在我的项目中,我循环遍历数据视图结果。

string html =string.empty; DataView dV = data.DefaultView; for(int i=0;i< dV.Count;i++) { DataRowView rv = dV[i]; html += rv.Row["X"].Tostring(); } 

dV中的行数总是3或4。

在这种情况下使用字符串concat + = opearator或StringBuilder更好吗?为什么?

我会在这里使用StringBuilder ,因为它描述了你正在做的事情。

对于3或4个字符串的简单连接,它可能不会产生任何显着差异,字符串连接甚至可能稍快一些 – 但如果你错了并且有很多行, StringBuilder将开始变得更有效率,而且它总是更能描述你正在做的事情。

或者,使用类似的东西:

 string html = string.Join("", dv.Cast() .Select(rv => rv.Row["X"])); 

请注意,此刻字符串之间没有任何类型的分隔符。 你确定那是你想要的吗? (另请注意,您的代码目前没有多大意义 – 您不是在循环中使用i 。为什么?)

我有一篇关于字符串连接的文章,它详细介绍了为什么值得使用StringBuilder以及何时使用。

编辑:对于那些怀疑字符串连接可能更快的人来说,这是一个测试 – 故意“讨厌”的数据,但只是为了certificate它是可能的:

 using System; using System.Diagnostics; using System.Text; class Test { static readonly string[] Bits = { "small string", "string which is a bit longer", "stirng which is longer again to force yet another copy with any luck" }; static readonly int ExpectedLength = string.Join("", Bits).Length; static void Main() { Time(StringBuilderTest); Time(ConcatenateTest); } static void Time(Action action) { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); // Make sure it's JITted action(); Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { action(); } sw.Stop(); Console.WriteLine("{0}: {1} millis", action.Method.Name, (long) sw.Elapsed.TotalMilliseconds); } static void ConcatenateTest() { string x = ""; foreach (string bit in Bits) { x += bit; } // Force a validation to prevent dodgy optimizations if (x.Length != ExpectedLength) { throw new Exception("Eek!"); } } static void StringBuilderTest() { StringBuilder builder = new StringBuilder(); foreach (string bit in Bits) { builder.Append(bit); } string x = builder.ToString(); // Force a validation to prevent dodgy optimizations if (x.Length != ExpectedLength) { throw new Exception("Eek!"); } } } 

在我的机器上的结果(用/o+ /debug-编译):

 StringBuilderTest: 2245 millis ConcatenateTest: 989 millis 

我已经多次运行,包括颠倒测试的顺序,结果是一致的。

建议使用StringBuilder ..为什么不对自己进行分析,然后决定什么是最适合你的..

 var stopWatch=new StopWatch(); stopWatch.Start(); string html =string.empty; DataView dV = data.DefaultView; for(int i=0;i< dV.Count;i++) { html += dV.Row["X"].Tostring(); } stopWatch.Stop(); Console.Write(stopWatch.EllapsedMilliseconds()); var stopWatch=new StopWatch(); stopWatch.Start(); string html =new StringBuilder(); DataView dV = data.DefaultView; for(int i=0;i< dV.Count;i++) { html.Append(dV.Row["X"].ToString()); } var finalHtml=html.ToString(); stopWatch.Stop(); Console.Write(stopWatch.EllapsedMilliseconds()); 

来自文档:

如果连接固定数量的String对象,则String类更适合并置操作。 在这种情况下,编译器甚至可以将单个串联操作组合成单个操作。

如果连接任意数量的字符串,则StringBuilder对象最好用于连接操作; 例如,如果循环连接随机数量的用户输入字符串。

所以在你的情况下我会说String更好。

编辑:

这是一个无休止的讨论,无论如何,我建议你检查你平均有多少opaeration并测试每个oparation的性能,以比较结果。

检查这个关于这个问题的好链接 ,包括一些性能测试代码。

StringBuilder肯定。 字符串是不可变的记住!

编辑:对于3-4行,串联将是Jon Skeet在他的回答中说的首选

建议使用StringBuilder 。 这是可变的。 它应该减少对内存分配器的压力:-)

字符串实例是不可变的。 创建后无法更改它。 任何看似更改字符串的操作都会返回一个新实例。

stringbuilder是你要找的。 一般来说,如果有某个工作的function尝试使用它而不是写一些做同样工作的程序。