C#中的string和StringBuilder之间的区别

C#中的string和StringBuilder之间的区别,第1张

C#中的string和StringBuilder之间的区别

一个

string
实例是不可变的。创建后便无法更改。似乎更改字符串的任何 *** 作都将返回一个新实例:

string foo = "Foo";// returns a new string instance instead of changing the old onestring bar = foo.Replace('o', 'a');string baz = foo + "bar"; // ditto here

不可变对象具有一些不错的属性,例如可以在线程中使用它们而不必担心同步问题,或者您可以直接直接分发私有支持字段,而不必担心有人更改了不应更改的对象(请参见数组或可变列表,如果不需要的话,通常需要在返回之前将其复制)。但是,如果不小心使用它们,可能会导致严重的性能问题(几乎所有问题–如果您需要一个以执行速度而自豪的语言为例,请查看C的字符串 *** 作函数)。

当您需要一个 可变的 字符串(例如您要分段构造的字符串或要在其中进行很多更改的字符串)时,您将需要一个

StringBuilder
,它是 可以
更改的字符缓冲区。在大多数情况下,这会影响性能。如果您想要一个可变的字符串,而不是对一个普通的
string
实例进行处理,那么最终将不必要地创建和销毁许多对象,而
StringBuilder
实例本身将发生变化,从而消除了对许多新对象的需求。

简单的示例:以下内容将使许多程序员感到痛苦:

string s = string.Empty;for (i = 0; i < 1000; i++) {  s += i.ToString() + " ";}

您最终将在此处创建2001个字符串,其中的2000个将被丢弃。使用StringBuilder的相同示例:

StringBuilder sb = new StringBuilder();for (i = 0; i < 1000; i++) {  sb.Append(i);  sb.Append(' ');}

这样可以减轻内存分配器的压力:-)

但是,应注意的是,对于字符串,C#编译器相当聪明。例如,以下行

string foo = "abc" + "def" + "efg" + "hij";

将由编译器加入,在运行时仅保留一个字符串。类似地,诸如

string foo = a + b + c + d + e + f;

将被重写为

string foo = string.Concat(a, b, c, d, e, f);

因此您不必为五个无意义的连接付费,这将是处理该连接的幼稚方式。这不会像上面那样在循环中节省您的时间(除非编译器展开循环,但我认为只有JIT可以这样做,并且最好不要打赌)。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5559851.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存