1.1 StringBuilder类型有什么作用?
众所周知,在.NET中String是引用类型,具有不可变性,当一个String对象被修改、插入、连接、截断时,新的String对象就将被分配,这会直接影响到性能。但在实际开发中经常碰到的情况是,一个String对象的最终生成需要经过一个组装的过程,而在这个组装过程中必将会产生很多临时的String对象,而这些String对象将会在堆上分配,需要GC来回收,这些动作都会对程序性能产生巨大的影响。事实上,在String的组装过程中,其临时产生的String对象实例都不是最终需要的,因此可以说是没有必要分配的。
鉴于此,在.NET中提供了StringBuilder,其设计思想源于构造器(Builder)设计模式,致力于解决复杂对象的构造问题。对于String对象,正需要这样的构造器来进行组装。StringBuilder类型在最终生成String对象之前,将不会产生任何String对象,这很好地解决了字符串操作的性能问题。
以下代码展示了使用StringBuilder和不适用StringBuilder的性能差异:(这里的性能检测工具使用了老赵的CodeTimer类)
public class Program { private const String item = "一个项目"; private const String split = ";"; static void Main(string[] args) { int number = 10000; // 使用StringBuilder CodeTimer.Time("使用StringBuilder: ", 1, () => { UseStringBuilder(number); }); // 不使用StringBuilder CodeTimer.Time("使用不使用StringBuilder: : ", 1, () => { NotUseStringBuilder(number); }); Console.ReadKey(); } static String UseStringBuilder(int number) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); for (int i = 0; i < number; i++) { sb.Append(item); sb.Append(split); } sb.Remove(sb.Length - 1, 1); return sb.ToString(); } static String NotUseStringBuilder(int number) { String result = ""; for (int i = 0; i < number; i++) { result += item; result += split; } return result; } }