String Concatenation Vs String Builder Append

时间:2009-12-29 04:50:57

标签: c#

所以......我有这个场景,我有一个Foreach循环,循环通过一个复选框列表来检查选中哪个。对于每个选中的复选框,我必须进行相当长的字符串连接,涉及30个平均长度为20个字符的不同字符串,然后将其作为HTTP请求发送出去。其中2个字符串取决于所选复选框的索引/值。

复选框列表的长度也可根据用户的数据而变化。我会说List的平均长度是20,但它可以达到50-60。因此,最糟糕的情况是整个字符串连接执行60次左右。

现在我通过'+'运算符进行简单的字符串连接,但是我想知道使用Stringbuilder进行简单的连接是否会更快。当然,这意味着我必须在循环中创建一个Stringbuilder对象,或者在循环之前创建它,并在发出HTTP请求后调用Stringbuilder.Remove。

我感谢任何人可以就此问题分享任何见解。

修改
感谢大家的所有回复,所以从我收集的内容来看,我这样做的最佳方式是:

 StringBuilder sb = new StringBuilder();
 foreach (CheckBox item in FriendCheckboxList)
 {
     if (item.Checked)
     {
         sb.Append(string1);
         sb.Append(string2);
         sb.Append(string3);
         .
         .
         .
         sb.Append(stringLast);

         SendRequest(sb.ToString());
         sb.Length = 0;
      }
  }

5 个答案:

答案 0 :(得分:14)

使用StringBuilder。这就是它的用途。

字符串是不可变的。字符串连接会创建一个新字符串,需要更多内存,通常被认为很慢:

string a = "John" + " " + "Saunders";

这会创建一个字符串“John”,然后创建另一个字符串“John Saunders”,最后将其分配给“a”。 “John”留给垃圾收集。

string a = "John";
a += " ";
a += "Saunders";

这大致相同,因为“John”被新的字符串“John”取代,后者被新的字符串“John Saunders”取代。原件留给垃圾收集。

另一方面,StringBuilder旨在追加,删除等等。


示例:

StringBuilder sb = new StringBuilder();
for (int i=0; i<n; i++)
{
    sb.Length = 0;
    sb.Append(field1[i]);
    sb.Append(field2[i]);
    ...
    sb.Append(field30[i]);
    // Do something with sb.ToString();
}

答案 1 :(得分:7)

这个主题多年来一直被分析为死亡。最终结果是,如果要进行少量已知的连接,请使用“+”,否则请使用stringbuilder。从你所说的,与'+'连接应该更快。有很多(赠送或采取)网站在那里分析这个 - 谷歌。

对于你所谈论的字符串的大小,它无论如何都可以忽略不计。

编辑:第二个想法,SB可能更快。但就像我说的,谁在乎?

答案 2 :(得分:7)

我知道这已经得到了回答,但我想指出我实际上认为总是使用StringBuilder的“盲目接受的福音”方法有时是错误的,这是一个案例。

有关背景信息,请参阅此博客文章:http://geekswithblogs.net/johnsperfblog/archive/2005/05/27/40777.aspx

缺点是,对于这种特殊情况,如上所述,通过避免使用StringBuilder并使用+运算符,您将看到更好的性能:

foreach (CheckBox item in FriendCheckboxList)
{
    if (item.Checked)
    {
        string request = string1 +
            string2 +
            string3 +
            .
            .
            .
           stringLast;
        SendRequest(request);
    }
}

原因是C#编译器(从.NET 1.1开始)将该语句转换为对String.Concat的单个IL调用,并将Strings数组作为参数传递。博客条目在概述String.Concat的实现细节方面做得非常出色,但足以说明,它对于这种情况非常有效。

答案 3 :(得分:2)

一般情况下,我建议使用StringBuilder

您是否对此进行了测试并检查了性能? 性能是一个问题与重写代码需要多长时间

答案 4 :(得分:2)

如果你问这个问题,很可能你应该使用StringBuilder有很多原因,但我会提供两个。

  1. 使用字符串连接时,必须分配新的缓冲区,并将另一个字符串中的数据复制到新的字符串变量中。因此,您将需要多次重复分配。这最终会破坏内存,使用堆空间,并为垃圾收集器做更多的工作。 另一方面,StringBuilder预先分配一个缓冲区,当你向它添加字符串时,不需要保持重新分配(假设初始缓冲区足够大)。这提高了性能,对内存的负担也大大降低。

  2. 作为开发者,我们应该尝试预测未来的增长。假设您的列表随着时间的推移而大幅增长,然后突然开始缓慢执行。如果你现在可以毫不费力地防止这种情况,你为什么不这样做呢?