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
是不可变的,因此任何"更改"字符串的操作实际上都将返回一个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