我理解String和StringBuilder之间的区别(StringBuilder是可变的),但两者之间有很大的性能差异吗?
我正在工作的程序有很多case驱动的字符串追加(500+)。使用StringBuilder是更好的选择吗?
我理解String和StringBuilder之间的区别(StringBuilder是可变的),但两者之间有很大的性能差异吗?
我正在工作的程序有很多case驱动的字符串追加(500+)。使用StringBuilder是更好的选择吗?
当前回答
字符串Vs字符串生成器:
你要知道的第一件事是这两个类生活在哪个汇编中?
So,
字符串出现在系统命名空间中。
and
StringBuilder出现在系统中。文本名称空间。
对于字符串声明:
您必须包括System名称空间。 就像这样。 使用系统;
and
对于StringBuilder声明:
你必须包括系统。文本名称空间。 就像这样。 使用text;
现在真正的问题来了。
string和StringBuilder之间的区别是什么?
两者的主要区别在于:
字符串是不可变的。
and
StringBuilder是可变的。
现在让我们讨论一下immutable和mutable的区别
Mutable::意思是可变的。
Immutable::表示不可更改。
例如:
using System;
namespace StringVsStrigBuilder
{
class Program
{
static void Main(string[] args)
{
// String Example
string name = "Rehan";
name = name + "Shah";
name = name + "RS";
name = name + "---";
name = name + "I love to write programs.";
// Now when I run this program this output will be look like this.
// output : "Rehan Shah RS --- I love to write programs."
}
}
}
在这种情况下,我们要将同一个对象改变5次。
所以显而易见的问题是!当我们修改同一个字符串5次时,实际上发生了什么。
这就是当我们改变同一个字符串5次时发生的情况。
让我们看一下图表。
解释:
当我们第一次将变量name初始化为Rehan时i-e string name = "Rehan" 这个变量被创建在堆栈“name”上,并指向“Rehan”值。 "name = name + "Shah"。引用变量不再指向对象“Rehan”,而是指向“Shah”,以此类推。
string是不可变的意思是一旦我们在内存中创建了对象我们就不能改变它们。
因此,当我们连接name变量时,前一个对象仍然在内存中,另一个新的字符串对象被创建。
所以从上图中我们有五件物品,四件物品被扔掉了,它们根本不用。它们仍然保留在内存中,并占据一定的内存容量。 “垃圾回收器”负责清理内存中的资源。
在字符串的情况下,当我们反复操作字符串时我们有很多对象被创建并留在内存中。
这就是字符串变量的故事。
现在让我们看看StringBuilder对象。 例如:
using System;
using System.Text;
namespace StringVsStrigBuilder
{
class Program
{
static void Main(string[] args)
{
// StringBuilder Example
StringBuilder name = new StringBuilder();
name.Append("Rehan");
name.Append("Shah");
name.Append("RS");
name.Append("---");
name.Append("I love to write programs.");
// Now when I run this program this output will be look like this.
// output : "Rehan Shah Rs --- I love to write programs."
}
}
}
在这种情况下,我们要将同一个对象改变5次。
所以显而易见的问题是!当我们修改同一个StringBuilder 5次时,实际上发生了什么。
这就是当我们修改同一个StringBuilder 5次时所发生的情况。
让我们看一下图表。
解释: 对于StringBuilder对象。你不会得到新对象。同一个对象会在内存中发生变化,所以即使你改变对象10000次,我们仍然只有一个stringBuilder对象。
你没有很多垃圾对象或非_referenced stringBuilder对象,因为它可以被更改。它是可变的意思是它会随着时间变化?
差异:
字符串存在于系统命名空间中,其中Stringbuilder存在 在系统。文本名称空间。 string是不可变的,而StringBuilder是可变的。
其他回答
除了前面的答案,当我想到这样的问题时,我总是做的第一件事是创建一个小型测试应用程序。在这个应用程序中,为这两种情况执行一些计时测试,看看哪个更快。
恕我直言,添加500+字符串条目绝对应该使用StringBuilder。
这个基准测试表明,当组合3个或更少字符串时,常规连接更快。
http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/
StringBuilder可以在内存使用方面做出非常显著的改进,特别是在将500个字符串加在一起的情况下。
考虑下面的例子:
string buffer = "The numbers are: ";
for( int i = 0; i < 5; i++)
{
buffer += i.ToString();
}
return buffer;
内存中发生了什么?创建以下字符串:
1 - "The numbers are: "
2 - "0"
3 - "The numbers are: 0"
4 - "1"
5 - "The numbers are: 01"
6 - "2"
7 - "The numbers are: 012"
8 - "3"
9 - "The numbers are: 0123"
10 - "4"
11 - "The numbers are: 01234"
12 - "5"
13 - "The numbers are: 012345"
通过将这5个数字加到字符串的末尾,我们创建了13个字符串对象!其中12个是无用的!哇!
StringBuilder fixes this problem. It is not a "mutable string" as we often hear (all strings in .NET are immutable). It works by keeping an internal buffer, an array of char. Calling Append() or AppendLine() adds the string to the empty space at the end of the char array; if the array is too small, it creates a new, larger array, and copies the buffer there. So in the example above, StringBuilder might only need a single array to contain all 5 additions to the string-- depending on the size of its buffer. You can tell StringBuilder how big its buffer should be in the constructor.
以“微优化剧场的悲剧”为例。
我已经看到,在StringBuilder的实例上使用EnsureCapacity(int capacity)方法调用,然后再将它用于任何字符串存储,可以显著提高性能。我通常在实例化后的代码行中调用它。它的效果和你这样实例化StringBuilder是一样的:
var sb = new StringBuilder(int capacity);
该调用会提前分配所需的内存,从而在多个Append()操作期间减少内存分配。您必须对需要多少内存做出有根据的猜测,但对于大多数应用程序来说,这应该不会太难。我通常会在内存过多的情况下犯错(我们说的是1k左右)。
在. net中,StringBuilder仍然比追加字符串快。我很确定在Java中,它们只是在附加字符串时在底层创建了一个StringBuffer,所以没有真正的区别。我不确定为什么他们还没有在。net中这样做。