Jun*_*r M 10 c# stringbuilder string-concatenation
StringBuilder与+连接相比,为什么速度较慢?
StringBuilder是为了避免额外的对象创建,但为什么它会惩罚性能?
static void Main(string[] args)
{
int max = 1000000;
for (int times = 0; times < 5; times++)
{
Console.WriteLine("\ntime: {0}", (times+1).ToString());
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
string msg = "Your total is ";
msg += "$500 ";
msg += DateTime.Now;
}
sw.Stop();
Console.WriteLine("String +\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
sw = Stopwatch.StartNew();
for (int j = 0; j < max; j++)
{
StringBuilder msg = new StringBuilder();
msg.Append("Your total is ");
msg.Append("$500 ");
msg.Append(DateTime.Now);
}
sw.Stop();
Console.WriteLine("StringBuilder\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
Console.Read();
}
Run Code Online (Sandbox Code Playgroud)

编辑:按建议移出范围变量:

seh*_*ehe 15
更改以便不会一直实例化StringBuilder,而是.Clear():
time: 1
String + : 3348ms
StringBuilder : 3151ms
time: 2
String + : 3346ms
StringBuilder : 3050ms
Run Code Online (Sandbox Code Playgroud)
等等
请注意,这仍然测试完全相同的功能,但尝试更智能地重用资源.
代码:(也住在http://ideone.com/YuaqY)
using System;
using System.Text;
using System.Diagnostics;
public class Program
{
static void Main(string[] args)
{
int max = 1000000;
for (int times = 0; times < 5; times++)
{
{
Console.WriteLine("\ntime: {0}", (times+1).ToString());
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
string msg = "Your total is ";
msg += "$500 ";
msg += DateTime.Now;
}
sw.Stop();
Console.WriteLine("String +\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
{
Stopwatch sw = Stopwatch.StartNew();
StringBuilder msg = new StringBuilder();
for (int j = 0; j < max; j++)
{
msg.Clear();
msg.Append("Your total is ");
msg.Append("$500 ");
msg.Append(DateTime.Now);
}
sw.Stop();
Console.WriteLine("StringBuilder\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
}
Console.Read();
}
}
Run Code Online (Sandbox Code Playgroud)
您正在为StringBuilder每次迭代创建一个新实例,这会产生一些开销.既然你没有将它用于它实际意图做的事情(即:构建大字符串,否则需要许多字符串连接操作),看到比串联更糟糕的性能并不奇怪.
更常见的比较/用法StringBuilder是:
string msg = "";
for (int i = 0; i < max; i++)
{
msg += "Your total is ";
msg += "$500 ";
msg += DateTime.Now;
}
StringBuilder msg_sb = new StringBuilder();
for (int j = 0; j < max; j++)
{
msg_sb.Append("Your total is ");
msg_sb.Append("$500 ");
msg_sb.Append(DateTime.Now);
}
Run Code Online (Sandbox Code Playgroud)
有了这个,你会发现StringBuilder和连接之间存在显着的性能差异.而"重要"是指数量级,而不是您在示例中观察到的~10%的差异.
由于StringBuilder不需要构建大量的中间字符串而不会被丢弃,因此可以获得更好的性能.这就是它的意思.对于较小的字符串,最好使用字符串连接以简化和清晰.