string和stringbuilder的个人总结

StringStringBuilder的深入解析

 

前言:本文出发点是我们开发的过程中是否真正的理解stringbuilder的使用,string字符串操作的是如何实现(哈希表),stringbuilder是否设置默认值容量,什么时候才用stringbuilder。

一概念Stringstringbulider的理解

string是我们用的最多的类型之一,是一个特殊的引用类型,直接派生于Object,因此它的值储存在托管堆上。构造一个新字符串的时候,不需要用new。它是”不可变的“。初始化字符串对象后,该字符串对象的长度、内容都是确定不变的了。可以思考这个时候,我们需要更改或者添加字符串,会做一个怎样的动作呢?

StringBulider因为string的”不可变“,导致多次修改字符串的时候会损耗性能,.net为了解决这个问题,提供了动态创建string的方法,以克服string不可变带来的性能损耗。StringBuilder和String比起来,功能较少,只有基本的属性和增删改的方法。但是你知道stringbuilder也有一个固定的容量值吗??注意:StringBulider容量  (默认是16虽然   StringBuilder   对象是动态对象,允许扩充它所封装的字符串中字符的数量,但是您可以为它可容纳的最大字符数指定一个值。此值称为该对象的容量,不应将它与当前   StringBuilder   对象容纳的字符串长度混淆在一起。例如,可以创建   StringBuilder   类的带有字符串“Hello”(长度为   5)的一个新实例,同时可以指定该对象的最大容量为   25。当修改   StringBuilder   时,在达到容量之前,它不会为其自己重新分配空间。当达到容量时,将自动分配新的空间且容量翻倍。可以使用重载的构造函数之一来指定StringBuilder类的容量。以下代码示例指定可以将   MyStringBuilder对象扩充到最大25个空白。 StringBuilder MyStringBuilder  =  new   StringBuilder("Hello   World!",   25);   另外,可以使用读/写   Capacity   属性来设置对象的最大长度。以下代码示例使用   Capacity   属性来定义对象的最大长度。  MyStringBuilder.Capacity   =   25;   EnsureCapacity   方法可用来检查当前   StringBuilder   的容量。如果容量大于传递的值,则不进行任何更改;但是,如果容量小于传递的值,则会更改当前的容量以使其与传递的值匹配。 也可以查看或设置   Length   属性。如果将   Length   属性设置为大于   Capacity   属性的值,则自动将   Capacity   属性更改为与   Length   属性相同的值。如果将   Length   属性设置为小于当前   StringBuilder   对象内的字符串长度的值,则会缩短该字符串。

、为什么说变动影响性能。(stringStringBuilder

 String:string s = "I am ";s += "Sky";怎么分配内存的呢?

备注:如果每次都这样重新分配真实疯了,.net肯定没有那么傻了,最起码要避免下如果两个string的字符串一模一样,我是不是不需要分配新的堆,只需要制定同样的引用就好了呢?下面就出现了一个名词:字符串留用,CLR初始化的时候会创建哈希表,每构建一个新字符串都会与哈希表匹配,查找是否有相同的字符串,如果匹配,就会返回这个已存在的旧对象,由新变量进行引用。否则,就会创建一个字符串副本添加到哈希表里,Key就是字符串,Value就是string对象在堆上的地址。

是不是所有的都是这样呢,有什么特殊情况吗?

总结New出来的对象是不会记录在哈希表。

tringBuilder 对象维护一个缓冲区,以便容纳新数据的串联。如果有足够的空间,新数据将被追加到缓冲区的末尾;否则,将分配一个新的、更大的缓冲区,原始缓冲区中的数据被复制到新的缓冲区,然后将新数据追加到新的缓冲区。

内部实现原理

总结:StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。事实是,StringBuilder比string快的原因是string拼接时产生了中间对象,最终是垃圾。如: string str = "a";str += "b";str += "c";那么,最终结果是"abc",但第二行产生了"ab"只是一个中间对象,是个垃圾。用StringBuilder会避免这种中间对象的产生。那如果我这么写呢? string str ="a"+"b"+ "c";这会比StringBuilder慢吗?不会。

中间对象的产生才是影响性能的主要原因。

 

三、测试案例:

 

private void button1_Click(object sender, EventArgs e)

{

int number =int.Parse( textBox1.Text.ToString());

GetStringTime(number);

GetStringBulider(number);

GetStringTime1(number);

GetStringBulider1(number);

}

/// <summary>

///  测试string 性能时间

/// </summary>

private void GetStringTime(int number)

{

Stopwatch watch = new Stopwatch();

List< String> li = new List< string>();

watch.Start();

string str = "select * from testa inner join 快速排序耗费时间 快速排序耗费时间 快速排序耗费时间";

for (int i = 0; i < number; i++)

{

li.Add(str);

}

watch.Stop();

label1.Text = watch.ElapsedMilliseconds.ToString();

}

private void GetStringBulider(int number)

{

Stopwatch watch = new Stopwatch();

List<String> li = new List<string>();

watch.Start();

StringBuilder strb = new StringBuilder();

strb.Append("select * from testa inner join dsadfasfsadfa快速排序耗费时间快速排序耗费时间");

for (int i = 0; i < number; i++)

{

li.Add(strb.ToString());

}

watch.Stop();

label2.Text = watch.ElapsedMilliseconds.ToString();

}

/// <summary>

///  测试string 性能时间变化

/// </summary>

private void GetStringTime1(int number)

{

Stopwatch watch = new Stopwatch();

List<String> li = new List<string>();

watch.Start();

string str = "select * from testa inner join 快速排序耗费时间 快速排序耗费时间 快速排序耗费时间";

for (int i = 0; i < number; i++)

{

str = str+"select * from testa inner join 快速排序耗费时间 快速排序耗费时间 快速排序耗费时间";

}

watch.Stop();

label1.Text =label1.Text+"不变,变化"+  watch.ElapsedMilliseconds.ToString();

}

/// <summary>

///  测试stringBulider  变化的性能

/// </summary>

/// <param name="number"></param>

private void GetStringBulider1(int number)

{

Stopwatch watch = new Stopwatch();

List<String> li = new List<string>();

watch.Start();

StringBuilder strb = new StringBuilder();

strb.Append("select * from testa inner join dsadfasfsadfa快速排序耗费时间快速排序耗费时间");

for (int i = 0; i < number; i++)

{

strb.Append("select * from testa inner join dsadfasfsadfa快速排序耗费时间快速排序耗费时间");

}

watch.Stop();

label2.Text =label2.Text+"不变,变化"+ watch.ElapsedMilliseconds.ToString();

}

效果图如下:

 

备注:每图第一行表示string,第二行表示stringbulider,变化表示str++的意思或append。

四:总结:String stringbulider的整体汇总。

1. Sting是恒定的,string部里的人是可变化的。

2. 对于简单的字符串连接操作,在性能上stringbuilder不一定总是优于string。因为stringbulider对象的创建也消耗大量的性能,在字符串连接比较少的情况下,过度滥用stringbuilder会导致性能的浪费而非节约,只有大量无法预知次数的字符串操作才考虑stringbuilder的使用。从最后分析可以看出如果是100行以内根本看不出太大差别。

3. Stringbulider的使用,最好制定合适的容量值,否则优于默认值容量不足而频繁的进行内存分配操作,是不妥的实现方法。

可以深思,第一我们对适合的容量值处理了吗? 第二,我们是不是一再提要使用stringbuilder说性能好,但是在100行内的字符操作有分别吗。

简单的字符串连接操作可以适度思考下 string.Concat 和 string.join 的使用。(string.concat的装箱操作)。

参考文章:

http://www.cnblogs.com/juqiang/archive/2005/04/19/140538.html

http://www.cnblogs.com/huangxincheng/p/4042105.html

http://www.cnblogs.com/heartstill/archive/2011/11/11/2245411.html

http://www.cnblogs.com/kid-li/archive/2006/10/18/532174.html

http://www.cnblogs.com/gfwei/archive/2007/03/14/674499.html

http://www.cnblogs.com/skychen1218/p/3593678.html

书籍:《你必须知道的.net》什么是string345页)

时间: 2024-11-07 02:40:17

string和stringbuilder的个人总结的相关文章

6-探秘Java中的String、StringBuilder以及StringBuffer

相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffer这几个类,分析它们的异同点以及了解各个类适用的场景.下面是本文的目录大纲: 一.你了解String类吗? 二.深入理解String.StringBuffer.StringBuilder 三.不同场景下三个类的性能测试 四.常见的关于String.StringBuffer的面试题(辟谣网上流传的一些曲解String类

Java字符串的String、StringBuilder、StringBuffer三者特性详解

一.不可变String类型 字符串是计算机程序设计中的,最常见行为,Java的字符串操作最主要的类是String,并且String对象是不可变的(Immutable),即对象一旦创建在内存中,那么它的内容就不再改变.虽然String类中提供很多方法看起来像是可以修改String对象,比如trim().subString()等等,但是实际上它们并没有改变原来的字符串对象,这些方法传递的只是引用的一个拷贝,所以重新创建了一个String类型的对象,并且有了新的引用. 例如下面一段代码可以说明Stri

String和StringBuilder、StringBuffer的区别

String和StringBuilder.StringBuffer的区别?     Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,它们可以储存和操作字符串.其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的.而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改.StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线

转:String StringBuffer StringBuilder区别

转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸裸的站在我们这些Java色狼面前了.嘿嘿.... 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通的类哦!!! [镜头1] String对象的创建       1.关于类对象的创建,很普通的一种方式就是利用构造器,

java中String与StringBuilder的区别

本篇文章介绍了,java中String与StringBuilder的区别. 相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,今天我在这里重新把这个概念给大家复习一下,顺便牵出 J2SE 5.0 里面带来的一个新的字符操作的类—— StringBuilder (先别忙着扔我砖头,我还算清醒,我这里说的不是 C #, Java 也有 StringBuilder 类).那么这个 StringBuilder 和

C#中string和StringBuilder的区别

string在任何语言中都有它的特殊性,在.NET中也是如此.它属于基本数据类型,也是基本数据类型中唯一的引用类型.字符串可以声明为常量,但它却放在了堆中. 一:不可改变对象 在.NET中String是不可改变对象,一旦创建了一个String对象并给它赋值,它就不可能再改变,也就是你不可能改变一个字符串的值.这句活初听起来似乎有些不可思议,大家也许马上会想到字符串连接操作,我们不也可以改变字符串吗?看下面的这段代码: public static void Main(string[] args)

【转】探秘Java中的String、StringBuilder以及StringBuffer

探秘Java中String.StringBuilder以及StringBuffer 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffer这几个类,分析它们的异同点以及了解各个类适用的场景.下面是本文的目录大纲: 一.你了解String类吗? 二.深入理解String.StringBuffer.StringBuilder 三.不同场景下三个类的性能测试 四.常见的关于

探秘Java中的String、StringBuilder以及StringBuffer(转载)

探秘Java中String.StringBuilder以及StringBuffer 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffer这几个类,分析它们的异同点以及了解各个类适用的场景.下面是本文的目录大纲: 一.你了解String类吗? 二.深入理解String.StringBuffer.StringBuilder 三.不同场景下三个类的性能测试 四.常见的关于

Part 59 to 60 Difference between Convert ToString and ToString,String and StringBuilder

Part 59 Difference between Convert ToString and ToString Part 60 Difference between String and StringBuilder

string和StringBuilder的区别,用法和详解

1.string 1.概念:string是引用类型,我们比较的是对象的值,而不是对象的本身. string strA="abcde"; string strB="abc"; string strC="de"; Console.WriteLine(strA == (strB+strC));//true Console.WriteLine((object)strA == (object)(strB+strC));//false 2.string对象是