String和StringBuilder-C#的性能注意事项

本文关键字:性能 注意事项 StringBuilder-C# String | 更新日期: 2023-09-27 18:05:53

全部,

对于字符串string s = "abcd"string w = s.SubString(2)是在内部返回新分配的string对象,即string w = new String ("cd"),还是返回string文本?

对于StringBuilder,在附加字符串值时,如果StringBuilder的大小需要增加,是否将所有内容复制到新的内存位置,或者只是将指向每个早期字符串值的指针重新分配到新位置?

String和StringBuilder-C#的性能注意事项

String是不可变的,因此任何"更改"字符串的操作实际上都将返回一个new string。这包括SubString和对String的所有其他操作,包括那些不更改长度的操作(如ToLower((或类似操作(。

StringBuilder在内部包含一个字符块的链接列表。当它需要增长时,会在列表的末尾分配并插入一个新的区块,并将数据复制到此处。换句话说,在追加时不会复制整个StringBuilder缓冲区,只复制正在追加的数据。我对照Framework4参考源对此进行了双重检查。

For the string string s = "abcd", does string w = s.SubString(2) return a new allocated String object?

For StringBuilder, when appending string values and if the size of the StringBuilder needs to be increased, are all the contents copied over to a new memory location?

字符串大小的任何更改都会导致新的字符串

如果要对字符串进行大量编辑,最好通过StringBuilder进行编辑。

来自MSDN:

对于对字符串值进行多次更改的操作,可以使用StringBuilder类而不是String类。与String类的实例不同,StringBuilder对象是可变的;当连接、追加或删除字符串中的子字符串时,操作是在单个字符串上执行的。

字符串是不可变的对象,因此每次必须进行更改时,都会创建该字符串的新实例。子字符串方法不会更改原始字符串的值。

谨致问候。

字符串StringBuilder之间的差异是一个重要概念,当应用程序必须处理大量字符串的编辑时,它会产生差异。

字符串

String对象是由属于System命名空间的System.Char对象表示的UTF-16代码单元的集合。由于这些对象的值是只读的,因此整个对象String被定义为不可变的。内存中String对象的最大大小为2GB,约为10亿个字符。

不可变不可变意味着每次使用System.String的方法时,都会在内存中创建一个新的sting对象,这会为新对象分配新的空间。

示例:通过使用字符串串联运算符+=显示名为test的字符串变量的值发生变化。事实上,它创建了一个新的String对象,该对象具有与原始对象不同的值和地址,并将其分配给测试变量。

string test;
test += "red"; // a new object string is created
test += "coding"; // a new object string is created
test += "planet"; // a new object string is created

StringBuilder

StringBuilder是一个动态对象,属于System.Text命名空间,允许修改它封装的字符串中的字符数,这种特性被称为可变性。

可突变性为了能够附加、删除、替换或插入字符,StringBuilder维护了一个缓冲区以容纳对字符串的扩展。如果新数据被附加到缓冲区(如果空间可用(;否则,分配一个新的、更大的缓冲区,将来自原始缓冲区的数据复制到新缓冲区,然后将新数据附加到新缓冲区时。

StringBuilder sb = new StringBuilder("");
sb.Append("red");
sb.Append("blue");
sb.Append("green ");
string colors = sb.ToString();

性能

为了帮助您更好地理解String和StringBuilder之间的性能差异,我创建了以下示例:

Stopwatch timer = new Stopwatch();
string str = string.Empty;
timer.Start();
for (int i = 0; i < 10000; i++) {
    str += i.ToString();
}
timer.Stop();
Console.WriteLine("String : {0}", timer.Elapsed);
timer.Restart();
StringBuilder sbr = new StringBuilder(string.Empty);
for (int i = 0; i < 10000; i++) {
    sbr.Append(i.ToString());
}
timer.Stop();
Console.WriteLine("StringBuilder : {0}", timer.Elapsed);

输出为

Output
String : 00:00:00.0706661
StringBuilder : 00:00:00.0012373