我实际上建立并运行了几个与此相关的测试。要查看测试结果,请跳至底部。我使用了以下基准测试方法:
public static string BenchmarkMethod(Action method, int iterations)
{
var watch = new Stopwatch();
var results = new List<TimeSpan>(iterations);
for (int iteration = 0; iteration < iterations; iteration++)
{
watch.Start();
method();
watch.Stop();
results.Add(watch.Elapsed);
watch.Reset();
}
var builder = new StringBuilder();
builder.Append("Method benchmarked: ");
builder.Append(method.Method.ReflectedType);
builder.Append(".");
builder.AppendLine(method.Method.Name);
builder.Append("Average time in ticks: ");
builder.AppendLine(results.Average(t => t.Ticks).ToString());
return builder.ToString();
}
我写了几个像这样的小方法:
public static void StringConcatOperatorX8()
{
var foo = strings[0] + strings[1] + strings[2] + strings[3] + strings[4] + strings[5] + strings[6] + strings[7] + strings[8];
}
并且:
public static void StringBuilderAppendsX8()
{
var builder = new StringBuilder();
builder.Append(strings[0]);
builder.Append(strings[1]);
builder.Append(strings[2]);
builder.Append(strings[3]);
builder.Append(strings[4]);
builder.Append(strings[5]);
builder.Append(strings[6]);
builder.Append(strings[7]);
builder.Append(strings[8]);
var result = builder.ToString();
}
其中strings
是一个包含9个30个字母字符串的字符串数组。
它们的连接/附加范围从1到8。我最初写了从1到6,使用3个字母字符串,并取了10,000个样本。
更新:我已经获得了更多的样本(确切地说是100万个),并将更多的字母添加到字符串中。显然,使用StringBuilder会浪费大量性能。在使用StringBuilder时,使用+
运算符所需的时间是它的两倍...现在测试需要几秒钟才能完成,我想我应该退出这个主题了。
最终更新:这也非常重要。当你在不同的行上进行连接时,使用+
运算符和StringBuilder的差异就出现了。这种方法实际上比使用StringBuilder还要慢:
public static void StringConcatAltOperatorX8()
{
var foo = strings[0];
foo += strings[1];
foo += strings[2];
foo += strings[3];
foo += strings[4];
foo += strings[5];
foo += strings[6];
foo += strings[7];
foo += strings[8];
}
如果每个字符串包含30个字符,共有100万个样本,在同一调用中将所有字符串合并成一个字符串大约需要5.809297个滴答声。将所有字符串分别合并在不同行中大约需要12.933227个滴答声。使用StringBuilder需要11.27558个滴答声。对于回复的长度,我很抱歉,这是我自己需要查证的事情。