StringBuilder类型有何作用
分析问题
String的性能问题产生于其内容不可修改的特性。当一个字符串对象被修改、插入、连接、截断时,新的字符串对象将被分配,这会影响性能。更加常见的情况是,一个字符串对象的最终生成需要经过一个组装的过程,而在这个组装过程中必将产生很多的临时字符串对象。这些对象在堆上分配,需要垃圾回收器来回收,这些动作都会对程序的性能产生巨大的影响。而事实上,在字符串组装过程中,其临时对象都不是最终需要的,可以说是无必要分配的。
这就产生了对StringBuilder类型的需求。StringBuilder类型的设计思想源于构造器的设计模式。构造器设计模式致力于解决复杂对象的构造问题,而对于字符串对象,正需要这样的构造器来进行组装。StringBuilder类型在最终生成String对象之前,将不会产生任何String对象,这很好地解决了字符串操作的性能问题。以下代码比较了使用StringBuiler和不使用StringBuilder的性能差异。
using System; using System.Text; namespace Test { class TestStringBuilder { private const string item = "A project"; private const string split = ";"; static void Main() { int number = 10000; //Use StringBuilder long sbStart = DateTime.Now.Ticks; UseStringBuilder(number); long sbEnd = DateTime.Now.Ticks; //Do not use StringBuilder long nsbStrat = DateTime.Now.Ticks; NotUseStringBuilder(number); long nsbEnd = DateTime.Now.Ticks; //Print string concatenation tacks time Console.WriteLine("Use StringBuilder:{0}", (sbEnd - sbStart).ToString()); Console.WriteLine("Do not use StringBuilder:{0}", (nsbEnd - nsbStrat).ToString()); Console.Read(); } //Use StringBuilder string concatenation static string UseStringBuilder(int number) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < number; i++) { sb.Append(item); sb.Append(split); } sb.Remove(sb.Length - 1, 1); return sb.ToString(); } //Do not use StringBuilder string concatenation static string NotUseStringBuilder(int number) { string result = string.Empty; for (int i = 0; i < number; i++) { result+=item; result += split; } result.Remove(result.Length - 1, 1); return result; } } }
如以上代码所示,使用StringBuilder同样可以操作字符串,这样的操作将不会产生任何的中间字符串变量,程序的结果是使用StringBuilder和不使用StringBuilder的性能比较:

StringBuilder类型内部保留了一个私有的String类型成员,当ToString方法被调用时,这个String类型成员将会被赋值并且返回给调用者。在字符串组装期间,这个字符串会在内存上内存上被修改。StringBuilder不仅仅提供了性能上更加优秀的字符串操作,它还能被用来和非托管代码进行交互。对于非托管代码,字符串的操作是直接基于内存的,如果使用字符串类型和非托管代码进行操作,那潜在地违反了字符串对象不可变的原则。所以StringBuilder常常被用来和非托管代码进行交互。
答案
StringBuilder采用构造器设计模式的思想高效地构造一个字符串对象,在构造过程中StringBuilder可以有效避免临时字符串对象的生成。一旦StringBuilder的ToString方法被调用后,最终的字符串就被生成,而随后的操作将导致一个新的字符串对象的分配。因为字符串对象的不可修改特性,StringBuilder还经常被用来和非托管代码交互。
posted on 2014-08-13 08:27 wangjinpeng_study 阅读(357) 评论(0) 收藏 举报
浙公网安备 33010602011771号