stringbuilder与string concat

Nir*_*bey 14 c# asp.net

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

 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();
 }
Run Code Online (Sandbox Code Playgroud)

dV中的行数总是3或4.

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

Jon*_*eet 37

我会StringBuilder在这里使用,因为它描述了你在做什么.

对于3个或4串的简单拼接,它可能不会作出任何显著差异,字符串连接可能甚至稍微快一点-但如果你错了,也有很多行,StringBuilder就会开始更高效,它总是更能描述你正在做的事情.

或者,使用类似的东西:

string html = string.Join("", dv.Cast<DataRowView>()
                                .Select(rv => rv.Row["X"]));
Run Code Online (Sandbox Code Playgroud)

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

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

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

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!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

StringBuilderTest: 2245 millis
ConcatenateTest: 989 millis
Run Code Online (Sandbox Code Playgroud)

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

  • @OD:不 - 如果它在一个循环中,它不是固定的.特别是,它不能用单个表达式表示(因此只能对Concat进行一次调用). (4认同)
  • @OD:这不是一个固定的数字 - 它在一个循环中.基本上,如果您可以在单个表达式中表达所有内容,则值得使用字符串连接.这不是这种情况. (2认同)
  • @JonSkeet:作为昨天刚买了你的书的人,我真的不敢在 C# 问题上与你争论,但看看这个比较:http://www.codeproject.com/Articles/14936/StringBuilder-vs-String-Fast -String-Operations-wit (2认同)
  • @Talha:你没有。您认识到,在循环中的字符串连接速度更快的情况下,差异几乎总是无关紧要的 - 因此您编写了更清晰的代码,*也*可以很好地扩展。 (2认同)

Baz*_*nga 5

建议使用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());
Run Code Online (Sandbox Code Playgroud)

  • @NirajChoubey:您是否有证据证明此代码的“性能”是相关的?增强可读性几乎总是更好的方法-并且`StringBuilder`在这里更清楚地表达您的意图。 (3认同)