casperOne正确指出这取决于数据。但是,假设您正在编写此作为类库供第三方使用 - 您会选择哪个呢?
一个选项是兼顾两者的优点 - 确定您实际需要添加多少数据,然后使用StringBuilder.EnsureCapacity确保我们只需要单个缓冲区调整大小。
如果我不是太在意的话,我会使用Append
x3 - 它似乎“更有可能”更快,因为在每次调用上解析字符串格式标记显然是无意义的工作。
请注意,我已要求BCL团队创建一种“缓存的格式化程序”,我们可以使用格式字符串创建并重复使用它。框架必须在每次使用时解析格式字符串,这太荒谬了。
编辑:好吧,我对John的代码进行了一些灵活性修改,并添加了一个“AppendWithCapacity”,它只是先计算所需容量。以下是不同长度的结果-对于长度1,我使用了1,000,000次迭代; 对于所有其他长度,我使用了100,000。 (这只是为了获得合理的运行时间。)所有时间均以毫秒为单位。
不幸的是,在SO中表格无法正常工作。长度分别为1、1000、10000、20000.
时间:
- Append:162,475,7997,17970
- AppendFormat:392,499,8541,18993
- AppendWithCapacity:139,189,1558,3085
所以,我从未看到AppendFormat能够胜过Append - 但我确实看到AppendWithCapacity赢得了很大的优势。
这是完整的代码:
using System;
using System.Diagnostics;
using System.Text;
public class StringBuilderTest
{
static void Append(string string1, string string2)
{
StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
}
static void AppendWithCapacity(string string1, string string2)
{
int capacity = string1.Length + string2.Length + 4;
StringBuilder sb = new StringBuilder(capacity);
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
}
static void AppendFormat(string string1, string string2)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}", string1, string2);
}
static void Main(string[] args)
{
int size = int.Parse(args[0]);
int iterations = int.Parse(args[1]);
string method = args[2];
Action<string,string> action;
switch (method)
{
case "Append": action = Append; break;
case "AppendWithCapacity": action = AppendWithCapacity; break;
case "AppendFormat": action = AppendFormat; break;
default: throw new ArgumentException();
}
string string1 = new string('x', size);
string string2 = new string('y', size);
action(string1, string2);
GC.Collect();
Stopwatch sw = Stopwatch.StartNew();
for (int i=0; i < iterations; i++)
{
action(string1, string2);
}
sw.Stop();
Console.WriteLine("Time: {0}ms", (int) sw.ElapsedMilliseconds);
}
}