欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅析C#中StringBuilder类的高效及与String的对比

程序员文章站 2023-11-22 14:56:04
在c#中,在处理字符串拼接的时候,使用stringbuilder的效率会比硬拼接字符串高很多。到底有多高,如下: static void main( string...

在c#中,在处理字符串拼接的时候,使用stringbuilder的效率会比硬拼接字符串高很多。到底有多高,如下:

static void main( string[] args )
{
 string str1 = string.empty;
 stopwatch sw1 = new stopwatch();
 sw1.start();
 for ( int i = 0; i < 10000; i++ )
 {
 str1 = str1 + i.tostring();
 }
 sw1.stop();
 console.writeline( "拼接字符串所耗费时间为:" + sw1.elapsedmilliseconds + "毫秒" );
 stringbuilder str2 = new stringbuilder( 10000 );
 stopwatch sw2 = new stopwatch();
 sw2.start();
 for ( int i = 0; i < 10000; i++ )
 {
 str2.append( i.tostring() );
 }
 sw2.stop();
 console.writeline( "使用stringbuilder所耗费时间为:" + sw2.elapsedmilliseconds + "毫秒" );
 console.readkey();
}

上面代码执行的效果如下:

浅析C#中StringBuilder类的高效及与String的对比

string类型的特别之处在于我们可以像使用值类型那样使用string类型,而实际上string是引用类型。既然是引用类型,clr就会把string类型保存在托管堆上。当我们使用str1 = str1 + i.tostring();进行拼接,由于string类型的恒定性,不会改变str1在内存中的地址,而是在托管堆上创建了另外一个字符串对象。如此,拼接10000次,就创建了10000个string类型对象,效率难免低下。

而stringbuilder会在内存中开辟一块连续的内存,当增加字符串实际上是针对同一块内存的修改,所以效率更高。

当然,到底使用硬拼接字符串,还是使用stringbuilder,不是绝对的,要看情况。当拼接字符串很少的情况下,当然直接硬拼接字符串就行了。

深入string和stringbuilder的区别
string对象是不可改变的。每次使用system.string类中的方法之一或者是进行运算时(如赋值、拼接等),都要在内存中创建一个新的字符串对象,这就需要为该新对象分配内存空间,而stringbuilder则不会。在需要对字符串执行重复修改操作时,与创建新的 string 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 system.text.stringbuilder 类。例如,当在一个循环中将许多字符串连接在一起时,使用 stringbuilder 类可以提升性能。

string类型对象的特点:
1.它是引用类型,在堆上分配内存
2.运算时会产生一个新的实例
3.string 对象一旦生成不可改变(immutable)
4.定义相等运算符(== 和 !=)是为了比较 string 对象的值(而不是引用)

大家都知道字符串对象是”不可变的”,
对字符串进行操作的方法实际上返回的是新的字符串对象。
在前面的示例中,将 s1 和 s2 的内容连接起来以构成一个字符串时,包含 "orange" 和 "red" 的两个字符串均保持不变。+= 运算符会创建一个包含组合内容的新字符串。结果是 s1 现在引用一个完全不同的字符串。只包含"orange" 的字符串仍然存在,但连接 s1 后将不再被引用。
大量的字符串相加的时候就会有很多想s1一样的 不在被引用,从而造成资源的极大浪费.
大家注意这点

string stringvalue = this.m_stringvalue;

internal volatile string m_stringvalue;

写到这里,需要有人见看到了 volatile,也许不明白是什么意思,大概的说下.
volatile关键字实现了线程间数据同步,用volatile修饰后的变量不允许有不同于”主”内存区域的变量拷贝。
换句话说,一个变量经volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即
获取到了相同的值。理所当然的,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的
变量拷贝更为高效。

this.needsallocation(stringvalue, requiredlength)

只有在需要的时候才去重新分配.
就分配空间和线程的使用上来讲,stringbuilder肯定比string要高,但是前提是使用频率比较高的情况下.