谈到stringbuile这个类颇有感触,记得第一次找工作的时候就被问到strung与stringbuilder的区别,当时回答的一塌糊涂。今天整理了一下,发布上来,希望对大家有所帮助。
String对象是恒定不变的,而System.Text.StringBuilder对象表示的字符串是可变的。StringBuilder是.NET提供的动态创建String对象的高效方式,以克服String对象恒定性带来的性能影响,克服了对String对象进行多次修改带来的创建大量String对象的问题。因此,我们首先将二者的执行性能做以简单的比较:
public static void Main()
{
#region 性能比较
Stopwatch sw = Stopwatch.StartNew();
//String性能测试
string str = "";
for (int i = 0; i < 10000; i++)
str += i.ToString();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
//StringBuilder性能测试
sw.Reset();
sw.Start();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
sb.Append(i.ToString());
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
#endregion
}
//执行结果
//422
//3
创建同样的字符串过程,执行结果有百倍之多的性能差别,而且这种差别会随着累加次数的增加而增加。因此,基于性能的考虑,我们应该尽可能使用StringBuilder来动态创建字符串,然后以ToString方法将其转换为String对象应用。StringBuilder内部有一个指向Char数值的字段,StringBuilder正是通过操作该字符数组而实现高效的处理机制。
1.构造StringBuilder StringBuilder对象的实例化没有什么特殊可言,与其他对象实例化一样,典型的构造方式为: StringBuilder sb = new StringBuilder("Hello, word.", 20); 其中,第二个参数表示容量,也就是StringBuilder所维护的字符数组的长度,默认为16,可以设定其为合适的长度来避免不必要的垃圾回收;还有一个概念为最大容量,表示字符串所能容纳字符的最大个数,默认为Int32.MaxValue,对象创建时一经设定就不可更改;字符串长度表示当前StringBuilder对象的字符数组长度,可以使用Length属性来获取和设定当前的StringBuilder长度。
2.StringBuilder的常用方法
(1)ToString方法 返回一个StringBuilder中字符数组字段的String,因为不必拷贝字符数组,所以执行效率很高,是最常用的方法之一。不过,值得注意的是,在调用了StringBuilder的ToString方法之后,都会导致StringBuilder重新分配和创建新的字符数组,因为ToString方法返回的String必须是恒定的。
(2)Append/AppendFormat方法 用于将文本或者对象字符串添加到当前StringBuilder字符数组中,例如:
StringBuilder sbs = new StringBuilder("Hello, ");
sbs.Append("Word.");
Console.WriteLine(sbs);
//执行结果 //Hello, Word.
而AppendFormat方法进一步实现了IFormattable接口,可接受IFormatProvider类型参数来实现可格式化的字符串信息,例如:
StringBuilder formatStr = new StringBuilder("The price is ");
formatStr.AppendFormat("{0:C}", 22);
formatStr.AppendFormat("/r/nThe Date is {0:D}", DateTime.Now.Date);
Console.WriteLine(formatStr);
(3)Insert方法 用于将文本或字符串对象添加到指定位置,例如:
StringBuilder mysb = new StringBuilder("My name XiaoWang");
mysb.Insert(8, "is ");
Console.WriteLine(mysb);
//执行结果 //My name is XiaoWang
(4)Replace方法 Replace方法是一种重要的字符串操作方法,用来将字符串数组中的一个字符或字符串替换为另外一个字符或字符串,例如:
StringBuilder sb = new StringBuilder("I love game.");
sb.Replace("game", ".NET");
Console.WriteLine(sb);
//执行结果 //I love .NET.
限于篇幅,我们不再列举其他方法,例如Remove、Equals、AppendLine等,留于读者自己来探索StringBuilder带来的快捷操作。
3.再论性能 StringBuilder有诸多的好处,是否可以代替String呢?基于这个问题我们有如下的对比性分析:
String是恒定的;而StringBuilder是可变的。
对于简单的字符串连接操作,在性能上StringBuilder不一定总是优于String。因为StringBuilder对象的创建代价较大,在字符串连接目标较少的情况下,过度滥用StringBuilder会导致性能的浪费而非节约。只有大量的或者无法预知次数的字符串操作,才考虑以StringBuilder来实现。
String类型的“+”连接操作,实际上是重载操作符“+”调用String.Concat来操作,而编译器则会优化这种连接操作的处理,编译器根据其传入参数的个数,一次性分配相应的内存,并依次拷入相应的字符串。
StringBuilder在使用上,最好指定合适的容量值,否则由于默认容量不足而频繁的进行内存分配操作,是不妥的实现方法。
通常情况下,进行简单字符串连接时,应该优先考虑使用String.Concat和String.Join等操作来完成字符串的连接,但是应该留意String.Concat可能存在的装箱操作。
原帖地址:http://www.sunxin.org/article/873.html