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)    收藏  举报

导航