我理解String和StringBuilder之间的区别(StringBuilder是可变的),但两者之间有很大的性能差异吗?

我正在工作的程序有很多case驱动的字符串追加(500+)。使用StringBuilder是更好的选择吗?


当前回答

StringBuilder明显更高效,但除非您进行大量的字符串修改,否则无法看到这种性能。

下面是给出性能示例的一小段代码。正如您所看到的,只有当您进入大型迭代时,您才真正开始看到主要的性能提升。

正如您所看到的,20万次迭代花费了22秒,而使用StringBuilder的100万次迭代几乎是瞬间完成的。

string s = string.Empty;
StringBuilder sb = new StringBuilder();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 50000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 200000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();
Console.WriteLine("Beginning Sb append at " + DateTime.Now.ToString());

for (int i = 0; i <= 1000000; i++)
{
    sb.Append("A");
}
Console.WriteLine("Finished Sb append at " + DateTime.Now.ToString());

Console.ReadLine();

以上代码的结果:

开头字符串+在28/01/2013 16:55:40。 完成字符串+在28/01/2013 16:55:40。 开头字符串+在28/01/2013 16:55:40。 完成字符串+在28/01/2013 16:56:02。 开始Sb追加在28/01/2013 16:56:02。 完成Sb的追加在28/01/2013 16:56:02。

其他回答

如果你要做很多字符串连接,使用StringBuilder。当您连接一个String时,每次都会创建一个新的String,这会占用更多的内存。

Alex

是的,StringBuilder在对字符串执行重复操作时提供了更好的性能。这是因为所有的更改都是对单个实例进行的,因此它可以节省大量时间,而不是像String那样创建一个新实例。

String Vs Stringbuilder

字符串 系统命名空间下 不可变(只读)实例 当价值发生持续变化时,性能下降 线程安全的 StringBuilder(可变字符串) 在系统。文本名称空间 可变的实例 显示更好的性能,因为对现有实例进行了新的更改

强烈推荐dotnet mob文章:c#中的String Vs StringBuilder。 相关堆栈溢出问题:字符串时的可变性 在c#中没有改变?

字符串连接将花费更多。 在Java中,您可以根据需要使用StringBuffer或StringBuilder。 如果您想要一个同步的、线程安全的实现,请使用StringBuffer。这将比字符串连接更快。

如果你不需要同步的或者线程安全的实现,选择StringBuilder。 这将比String连接更快,也比StringBuffer更快,因为它们没有同步开销。

为了澄清Gillian所说的4弦,如果你有这样的东西:

string a,b,c,d;
 a = b + c + d;

那么使用字符串和加号运算符会更快。这是因为(就像Eric指出的Java一样),它在内部自动使用StringBuilder(实际上,它使用StringBuilder也使用的原语)

但是,如果你正在做的事情接近:

string a,b,c,d;
 a = a + b;
 a = a + c;
 a = a + d;

然后你需要显式地使用一个StringBuilder。. net在这里不会自动创建一个StringBuilder,因为这毫无意义。在每行的末尾,"a"必须是一个(不可变的)字符串,因此它必须在每行上创建和释放一个StringBuilder。为了提高速度,你需要使用相同的StringBuilder,直到你完成构建:

string a,b,c,d;
StringBuilder e = new StringBuilder();
 e.Append(b);
 e.Append(c);
 e.Append(d);
 a = e.ToString();

一个简单的例子来演示使用String连接和StringBuilder在速度上的差异:

System.Diagnostics.Stopwatch time = new Stopwatch();
string test = string.Empty;
time.Start();
for (int i = 0; i < 100000; i++)
{
    test += i;
}
time.Stop();
System.Console.WriteLine("Using String concatenation: " + time.ElapsedMilliseconds + " milliseconds");

结果:

使用字符串串联:15423毫秒

StringBuilder test1 = new StringBuilder();
time.Reset();
time.Start();
for (int i = 0; i < 100000; i++)
{
    test1.Append(i);
}
time.Stop();
System.Console.WriteLine("Using StringBuilder: " + time.ElapsedMilliseconds + " milliseconds");

结果:

使用StringBuilder: 10毫秒

结果,第一次迭代花费了15423毫秒,而使用StringBuilder的第二次迭代花费了10毫秒。

在我看来,使用StringBuilder更快,快得多。