我理解String和StringBuilder之间的区别(StringBuilder是可变的),但两者之间有很大的性能差异吗?

我正在工作的程序有很多case驱动的字符串追加(500+)。使用StringBuilder是更好的选择吗?


当前回答

这个基准测试表明,当组合3个或更少字符串时,常规连接更快。

http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/

StringBuilder可以在内存使用方面做出非常显著的改进,特别是在将500个字符串加在一起的情况下。

考虑下面的例子:

string buffer = "The numbers are: ";
for( int i = 0; i < 5; i++)
{
    buffer += i.ToString();
}
return buffer;

内存中发生了什么?创建以下字符串:

1 - "The numbers are: "
2 - "0"
3 - "The numbers are: 0"
4 - "1"
5 - "The numbers are: 01"
6 - "2"
7 - "The numbers are: 012"
8 - "3"
9 - "The numbers are: 0123"
10 - "4"
11 - "The numbers are: 01234"
12 - "5"
13 - "The numbers are: 012345"

通过将这5个数字加到字符串的末尾,我们创建了13个字符串对象!其中12个是无用的!哇!

StringBuilder fixes this problem. It is not a "mutable string" as we often hear (all strings in .NET are immutable). It works by keeping an internal buffer, an array of char. Calling Append() or AppendLine() adds the string to the empty space at the end of the char array; if the array is too small, it creates a new, larger array, and copies the buffer there. So in the example above, StringBuilder might only need a single array to contain all 5 additions to the string-- depending on the size of its buffer. You can tell StringBuilder how big its buffer should be in the constructor.

其他回答

使用字符串进行连接会导致运行时复杂度达到O(n^2)的量级。

如果使用StringBuilder,需要复制的内存就会少得多。使用StringBuilder(int capacity),如果您可以估计最终字符串的大小,则可以提高性能。即使不精确,也可能只需要将StringBuilder的容量增加几倍,这也有助于提高性能。

我相信StringBuilder更快,如果你有超过4个字符串,你需要附加在一起。此外,它可以做一些很酷的事情,如AppendLine。

字符串Vs字符串生成器:

你要知道的第一件事是这两个类生活在哪个汇编中?

So,

字符串出现在系统命名空间中。

and

StringBuilder出现在系统中。文本名称空间。

对于字符串声明:

您必须包括System名称空间。 就像这样。 使用系统;

and

对于StringBuilder声明:

你必须包括系统。文本名称空间。 就像这样。 使用text;

现在真正的问题来了。

string和StringBuilder之间的区别是什么?

两者的主要区别在于:

字符串是不可变的。

and

StringBuilder是可变的。

现在让我们讨论一下immutable和mutable的区别

Mutable::意思是可变的。

Immutable::表示不可更改。

例如:

using System;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // String Example

            string name = "Rehan";
            name = name + "Shah";
            name = name + "RS";
            name = name + "---";
            name = name + "I love to write programs.";

            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah RS --- I love to write programs."
        }
    }
}

在这种情况下,我们要将同一个对象改变5次。

所以显而易见的问题是!当我们修改同一个字符串5次时,实际上发生了什么。

这就是当我们改变同一个字符串5次时发生的情况。

让我们看一下图表。

解释:

当我们第一次将变量name初始化为Rehan时i-e string name = "Rehan" 这个变量被创建在堆栈“name”上,并指向“Rehan”值。 "name = name + "Shah"。引用变量不再指向对象“Rehan”,而是指向“Shah”,以此类推。

string是不可变的意思是一旦我们在内存中创建了对象我们就不能改变它们。

因此,当我们连接name变量时,前一个对象仍然在内存中,另一个新的字符串对象被创建。

所以从上图中我们有五件物品,四件物品被扔掉了,它们根本不用。它们仍然保留在内存中,并占据一定的内存容量。 “垃圾回收器”负责清理内存中的资源。

在字符串的情况下,当我们反复操作字符串时我们有很多对象被创建并留在内存中。

这就是字符串变量的故事。

现在让我们看看StringBuilder对象。 例如:

using System;
using System.Text;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // StringBuilder Example

            StringBuilder name = new StringBuilder();
            name.Append("Rehan");
            name.Append("Shah");
            name.Append("RS");
            name.Append("---");
            name.Append("I love to write programs.");


            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah Rs --- I love to write programs."
        }
    }
}

在这种情况下,我们要将同一个对象改变5次。

所以显而易见的问题是!当我们修改同一个StringBuilder 5次时,实际上发生了什么。

这就是当我们修改同一个StringBuilder 5次时所发生的情况。

让我们看一下图表。

解释: 对于StringBuilder对象。你不会得到新对象。同一个对象会在内存中发生变化,所以即使你改变对象10000次,我们仍然只有一个stringBuilder对象。

你没有很多垃圾对象或非_referenced stringBuilder对象,因为它可以被更改。它是可变的意思是它会随着时间变化?

差异:

字符串存在于系统命名空间中,其中Stringbuilder存在 在系统。文本名称空间。 string是不可变的,而StringBuilder是可变的。

如果你要做很多字符串连接,使用StringBuilder。当您连接一个String时,每次都会创建一个新的String,这会占用更多的内存。

Alex

从内存的角度来看,StringBuilder的性能会更好。至于处理,执行时间的差异可以忽略不计。