string
和之间有什么区别StringBuilder
?
另外,有什么例子可以理解?
Answers:
一个string
实例是不可变的。创建后便无法更改。似乎更改字符串的任何操作都将返回一个新实例:
string foo = "Foo";
// returns a new string instance instead of changing the old one
string 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可以这样做,最好不要对此押注)。
串
在系统名称空间下
不可变(只读)实例
当价值不断变化时,性能会下降
线程安全
StringBuilder(可变字符串)
有关此主题的描述性的文章有很多的例子使用ObjectIDGenerator,遵循此链接。
相关的堆栈溢出问题:当C#中的字符串不变时,字符串的可变性
串
String实例是不可变的,也就是说,创建后我们无法更改它。如果我们对String执行任何操作,它将返回一个新实例(在内存中创建一个新实例),而不是修改现有实例值。
StringBuilder
StringBuilder是可变的,也就是说,如果我们在StringBuilder上执行任何操作,它将更新现有实例值,并且不会创建新实例。
String对象是不可变的。每次使用System.String类中的一种方法时,都会在内存中创建一个新的字符串对象,这需要为该新对象分配新的空间。在需要对字符串进行重复修改的情况下,与创建新的String对象相关的开销可能会非常昂贵。当您要修改字符串而不创建新对象时,可以使用System.Text.StringBuilder类。例如,当将多个字符串串联在一起时,使用StringBuilder类可以提高性能。
当您需要分多个步骤构建字符串时,StringBuilder将为您提供帮助。
而不是这样做:
String x = "";
x += "first ";
x += "second ";
x += "third ";
你做
StringBuilder sb = new StringBuilder("");
sb.Append("first ");
sb.Append("second ");
sb.Append("third");
String x = sb.ToString();
最终效果是相同的,但是StringBuilder将使用更少的内存并且运行得更快。与其创建一个新的字符串(不是两者的串联),它会分别创建块,并且只有在最后才将它们组合在一起。
字符串是不可变的,即,如果更改它们的值,则旧值将被丢弃,并在堆上创建新值,而在字符串生成器中,我们可以修改现有值而无需创建新值。
因此,性能方面的String Builder是有益的,因为我们不需要占用更多的内存空间。
字符串(System.String)是.NET框架内定义的类型。String类是不可变的。这意味着每次对System.String实例执行操作时,.NET编译器都会创建该字符串的新实例。该操作对开发人员隐藏。
System.Text.StringBuilder是表示可变字符串的类。此类提供了一些有用的方法,这些方法使用户能够管理由StringBuilder包装的String。请注意,所有操作都在同一StringBuilder实例上进行。
Microsoft鼓励使用StringBuilder,因为它在内存使用方面更为有效。
同样,字符串连接的复杂度为O(N2),而对于StringBuffer,复杂度为O(N)。
因此,由于每次都会创建许多新对象,因此在循环中使用串联时可能会出现性能问题。
System.String是一个可变对象,这意味着在创建之后就无法对其进行修改。请参考C#中的string和StringBuilder之间的区别?以便更好地理解。
字符串是不可变的类型。这意味着,每当您开始将字符串彼此串联时,每次都会创建新的字符串。如果执行多次,最终将导致大量堆开销和内存不足的风险。
StringBuilder实例用于将字符串追加到同一实例,从而在您调用ToString方法时创建一个字符串。
由于实例化StringBuilder对象的开销,Microsoft表示,当您有5-10个以上的字符串串联时,使用它很有用。
对于示例代码,我建议您在这里看看: