.Net 中的 string、String、StringBuffer 内存处理性能 和 应用场景
一、System.String
string
等价于 System.String
。
string
是 System.String
的别名。
声明:
1 string a1 = null; // 仅仅是一个声明,内存中并没有分配用来存储值的空间。 2 3 string a1 = String.Empty; // 等价于 "",以新建字符串长度为零的 String 对象,可以减少 NullReferenceException 发生的可能性。 4 5 System.String greeting = "Hello World!"; // 在内存中分配了一个连续性的不可变的储存空间。 6 7 // 长字符串字面量拆分为较短的字符串,从而提高源代码的可读性。 8 // 以下代码将较短的字符串连接起来,以创建长字符串字面量。 在编译时将这些部分连接成一个字符串。 无论涉及到多少个字符串,均不产生运行时性能开销。 9 string text = "Historically, the world of data and the world of objects " + 10 "have not been well integrated. Programmers work in C# or Visual Basic " + 11 "and also in SQL or XQuery. On the one side are concepts such as classes, " + 12 "objects, fields, inheritance, and .NET Framework APIs. On the other side " + 13 "are tables, columns, rows, nodes, and separate languages for dealing with " + 14 "them. Data types often require translation between the two worlds; there are " + 15 "different standard functions. Because the object world has no notion of query, a " + 16 "query can only be represented as a string without compile-time type checking or " + 17 "IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " + 18 "objects in memory is often tedious and error-prone.";
System.String
是不可变类型。 也就是说,出现的用于修改对象的每个操作 System.String
实际上都会创建一个新的字符串。
如下举例:
1 // 初始化 s1 2 // 内存为 s1 分配了存放字符的空间 3 string s1 = "A string is more "; 4 5 // 初始化 s2 6 // 内存为 s2 分配了存放字符的空间 7 string s2 = "than the sum of its chars."; 8 9 // 内存为 s1 重新分配了新值的空间 10 // 并指向新空间的地址,所以 s1 有了新的值 11 // 无用的s1旧值等待GC垃圾回收 12 s1 += s2; 13 14 System.Console.WriteLine(s1);
以上,假设更多的+或+=等的多次赋值s1,那么 内存在不停的开辟新的空间存放新值赋予s1 … … 每次再需要GC分配、压缩、清理… …
对于执行大量字符串操作的例程 (例如在循环中多次修改字符串的应用程序) ,重复修改字符串可能会显著降低性能。
二、System.Text.StringBuilder
System.Text.StringBuilder
对象在缓冲区操作,是一个可变字符串类,缓冲区可随时增加或减少或删除或替换等的字符串的长度。
StringBuilder strb = new StringBuilder(); strb.Append('*', 10).Append(" Adding Text to a StringBuilder Object ").Append('*', 10); strb.AppendLine("\n"); strb.AppendLine("Some code points and their corresponding characters:"); for (int ctr = 50; ctr <= 60; ctr++) { strb.AppendFormat("{0,12:X4} {1,12}", ctr,Convert.ToChar(ctr)); strb.AppendLine(); }
三、适用场景
string、String |
StringBuilder |
连续性的不可变的内存空间长度; 开辟新的内存空间存放变更后的值; 借助IndexOf、Substring等进行字符搜索。 |
缓冲区可伸缩的内存空间长度; (Chars[])字符搜索方式复杂。 |
字符更改次数很少; 固定数量的串联拼接操作; 大量的字符串搜索。 |
大量的未知的不确定的更改次数; 字符串非搜索场景 |